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.
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 msThe 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 方法 → AOPConclusion
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
