Stop Hand‑Writing Logs: One‑Click Full‑Trace Monitoring with Spring Boot AOP

After a system has been running, developers often drown in manual log statements to answer questions like why an interface is slow, who called a method, or what parameters were passed, but Spring Boot AOP lets you replace all that with a single annotation and aspect that automatically records calls, execution time, parameters, exceptions, and call chains, keeping business code clean.

LuTiao Programming
LuTiao Programming
LuTiao Programming
Stop Hand‑Writing Logs: One‑Click Full‑Trace Monitoring with Spring Boot AOP

Problem

When a system runs for a while developers often add explicit log.info statements to answer questions such as “Why is this interface slow?”, “Who called this method?”, and “What parameters were passed?”. The code becomes cluttered with repetitive logging, and maintenance cost rises because every method and module needs its own log statements.

Solution Overview

Spring AOP can capture interface call logs, execution time, parameters, exceptions, and call‑chain information with a single aspect and a custom annotation, eliminating the need for explicit log statements in business code.

Custom Log Annotation

Create an annotation to mark methods that require monitoring.

package com.icoderoad.annotation;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogTrace {
    String value() default "";
}

AOP Aspect

Place the aspect under /src/main/java/com/icoderoad/aspect. The aspect records parameters, execution time, and exceptions for any method annotated with @LogTrace.

package com.icoderoad.aspect;

import com.icoderoad.annotation.LogTrace;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class LogAspect {
    @Around("@annotation(logTrace)")
    public Object around(ProceedingJoinPoint joinPoint, LogTrace logTrace) throws Throwable {
        long start = System.currentTimeMillis();
        String methodName = joinPoint.getSignature().toShortString();
        Object[] args = joinPoint.getArgs();
        log.info("开始执行方法: {}", methodName);
        log.info("请求参数: {}", args);
        try {
            Object result = joinPoint.proceed();
            long cost = System.currentTimeMillis() - start;
            log.info("方法执行完成: {}", methodName);
            log.info("执行耗时: {} ms", cost);
            return result;
        } catch (Exception e) {
            log.error("方法异常: {}", methodName, e);
            throw e;
        }
    }
}

Zero‑Intrusion Business Code

Business classes only need to add the @LogTrace annotation.

package com.icoderoad.service;

import com.icoderoad.annotation.LogTrace;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
    @LogTrace("创建订单")
    public String createOrder(String userId) {
        try { Thread.sleep(120); } catch (InterruptedException ignored) {}
        return "ORDER_1001";
    }
}
package com.icoderoad.controller;

import com.icoderoad.service.OrderService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/order")
public class OrderController {
    private final OrderService orderService;
    public OrderController(OrderService orderService) { this.orderService = orderService; }
    @GetMapping("/create")
    public String create() { return orderService.createOrder("user_1"); }
}

Runtime Example

Calling GET /order/create produces logs:

开始执行方法: OrderService.createOrder
请求参数: [user_1]
方法执行完成: OrderService.createOrder
执行耗时: 121 ms

The business code itself contains no log statements.

Advanced AOP Uses

1. Interface Performance Statistics

long cost = System.currentTimeMillis() - start;
if (cost > 1000) {
    log.warn("慢接口: {} 耗时 {} ms", methodName, cost);
}

2. Automatic Exception Alerts

catch (Exception e) {
    alarmService.notify("接口异常: " + methodName);
    throw e;
}

3. Automatic Audit Logging

AuditLog log = new AuditLog();
log.setUserId(userId);
log.setAction(methodName);
log.setTime(LocalDateTime.now());
auditRepository.save(log);

Production Practices

Do not log sensitive data; mask values such as passwords.

Avoid serializing large objects (e.g., HttpServletRequest) directly; log only required fields.

Re‑throw caught exceptions to preserve transaction integrity.

AOP vs. Interceptor

Interceptor : applies to HTTP requests.

AOP : applies to method invocations.

Typical mapping:

HTTP 请求 → Interceptor
Service 方法 → AOP

Conclusion

Using a single AOP aspect and a custom annotation separates cross‑cutting concerns (logging, timing, exception handling) from business logic, improves code readability, and reduces maintenance effort.

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.

JavaAOPPerformance MonitoringLoggingSpring BootAnnotationAspectJ
LuTiao Programming
Written by

LuTiao Programming

LuTiao Programming is a friendly community offering free programming lessons. We inspire learners to explore new ideas and technologies and quickly acquire job-ready skills.

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.