From AOP Annotations to Binlog: Evolving Business Operation Logging Strategies

This article examines the progressive design of business operation logging—from a basic AOP‑annotation approach, through an AOP‑SpEL enhancement, to a binlog‑based time‑window solution—detailing each method's implementation steps, trade‑offs, and practical considerations for robust audit and monitoring in enterprise systems.

Architect
Architect
Architect
From AOP Annotations to Binlog: Evolving Business Operation Logging Strategies

Background

The system sits at the core of a business data flow, receiving upstream data and forwarding user‑generated operation data downstream. To answer the question “who performed what on which object at which time”, the team decided to record the full lifecycle of core business data via operation logs.

Benefits of Business Operation Logs

Audit & Compliance : Captures actor, action, timestamp and target data for traceability.

Security : Enables intrusion detection and post‑incident analysis.

Error Diagnosis & System Monitoring : Provides fault‑tracing information and performance metrics such as response time and resource consumption.

User‑Behavior Analysis : Supplies business insights for product improvement and customer‑service troubleshooting.

Data Recovery : Allows reconstruction of lost or corrupted data by replaying operation logs.

Business Rule & Process Improvement : Supports analysis and optimisation of workflows.

Goal

Enhance data traceability and transparency so that every operation can be answered by the question: Who performed what on which object at which time?

Solution 1.0 – AOP + Annotation

Using Spring AOP, a custom annotation marks methods that need logging. An aspect intercepts the annotated methods, records execution time and logs basic information.

Define the Log Annotation

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {
    String value() default "";
    // additional attributes such as operation type, level, etc.
}

Create the AOP Aspect

@Aspect
@Component
public class LoggingAspect {
    @Around("@annotation(loggable)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint, Loggable loggable) throws Throwable {
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed(); // execute target method
        long executionTime = System.currentTimeMillis() - start;
        // record log
        logger.info(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    }
}

Spring Configuration & Usage

@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
    // other beans may be defined here
}

public class SomeService {
    @Loggable
    public void someBusinessMethod(Object param) {
        // business logic
    }
}

Extended Log Recording Logic

The aspect can be expanded to capture method parameters, return values, exceptions, and timestamps.

@Autowired
private Logger logger; // e.g., SLF4J logger

@Around("@annotation(loggable)")
public Object logBusinessOperation(ProceedingJoinPoint joinPoint, Loggable loggable) throws Throwable {
    long start = System.currentTimeMillis();
    try {
        Object result = joinPoint.proceed();
        return result;
    } catch (Exception e) {
        // record exception details
        throw e;
    } finally {
        long executionTime = System.currentTimeMillis() - start;
        logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
    }
}

Shortcomings of Solution 1.0

Log Granularity : The aspect can only access limited context, insufficient for a complete operation record.

Business Scenario Awareness : The aspect is not business‑aware, making it hard to delineate new operation scopes.

Cascade Operations : When multiple tables or services are involved, the aspect records each method separately, losing the overall transaction chain.

Solution 2.0 – AOP + SpEL

To enrich log content, Spring Expression Language (SpEL) is introduced so that annotation attributes can be dynamically evaluated against method parameters.

What is SpEL?

SpEL is Spring’s expression language that can evaluate object properties, invoke methods, and perform arithmetic or logical operations at runtime. It is already used implicitly in annotations like @Value.

Extended LogRecord Annotation

@Repeatable(LogRecords.class)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface LogRecord {
    String success();
    String fail() default "";
    String operator() default ""; // who performed the action
    String type(); // business module
    String subType() default ""; // sub‑module
    String bizNo(); // business identifier
    String extra() default ""; // extra info
    String actionType(); // e.g., edit, create, delete
}

SpEL Parser for Annotation Attributes

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

public class LogRecordParser {
    public static Map<String, Object> parseLogRecord(Annotation logRecordAnnotation) {
        Map<String, Object> result = new HashMap<>();
        ExpressionParser parser = new SpelExpressionParser();
        for (String attribute : logRecordAnnotation.getAttributeNames()) {
            Object value = logRecordAnnotation.getAttribute(attribute);
            Expression expression = parser.parseExpression((String) value);
            Object parsedValue = expression.getValue(); // simplified for illustration
            result.put(attribute, parsedValue);
        }
        return result;
    }
}

Developers can now write expressions such as #{#param.id} inside the annotation to capture method arguments.

Pros & Cons of Solution 2.0

Pros: Reduces repetitive code, allows richer context capture via SpEL, and keeps integration relatively lightweight.

Cons: Still introduces many custom annotations (intrusive) and requires product‑level consensus on log content definitions.

Solution 3.0 – Binlog + Time Window

Application‑level interception misses low‑level data changes, so the team turned to MySQL binlog as the source of truth.

What is Binlog?

Binlog records every SQL statement that modifies data (INSERT, UPDATE, DELETE) in a binary format, enabling reconstruction of data changes.

Problems & Idea

Problem 1 : Binlog events are unordered and may span multiple tables without a surrounding transaction, complicating correlation.

Problem 2 : The operator (who performed the change) is often missing because applications may not set it explicitly.

To address ordering, Flink’s sliding time‑window concept is borrowed: group binlog events into fixed‑size windows (e.g., 1‑minute) so that events belonging to the same logical transaction can be processed together.

Time‑Window Example

With a 1‑minute rolling window, each incoming binlog row is assigned to the window that covers its timestamp. After the window closes, the collected rows are correlated based on foreign‑key references.

Time window diagram
Time window diagram

Data Model for Binlog Parsing

@Data
public static class RowChange {
    private int tableId;
    private List<RowDatas> rowDatas;
    private String eventType;
    private boolean isDdl;
}

@Data
public static class RowDatas {
    private List<DataColumn> afterColumns;
    private List<DataColumn> beforeColumns;
}

@Data
public static class DataColumn {
    private int sqlType;
    private boolean isNull;
    private String mysqlType;
    private String name;
    private boolean isKey;
    private int index;
    private boolean updated;
    private String value;
}

Architecture Overview

The final architecture consists of a binlog collector, a windowing processor that groups events, and a downstream service that enriches each event with operator information (e.g., via ORM interceptors) before persisting the unified operation log.

Overall architecture diagram
Overall architecture diagram

Pros & Cons of Solution 3.0

Pros: Captures low‑level data changes directly from the database, reduces application‑level code, and can be reused across multiple services.

Cons: Binlog also contains non‑business changes (batch jobs, maintenance), making filtering harder; business‑level semantics are weaker compared with annotation‑based approaches.

Conclusion

The evolution from a simple AOP‑annotation method to a binlog‑driven, window‑based pipeline illustrates the trade‑offs between invasiveness, data richness, and operational complexity. Teams should select the approach that best fits their existing stack, data‑volume characteristics, and governance requirements.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendaopspringSpELloggingBinlog
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.