日志模块自定义@SkipLogAspect注解跳过切面
文章目录
- 1.增加原因
- 2.common-log4j2-starter
- 1.目录结构
- 2.SkipLogAspect.java 自定义注解
- 3.LogAspect.java
- 1.核心改动
- 2.完整代码
- 3.common-log4j2-starter-demo
- 1.目录结构
- 2.TraceController.java 新增方法,测试跳过日志切面的注解
- 3.测试
1.增加原因
因为如果参数是一些大对象,比如HttpServletRequest request,在转化为json的时候就会导致OOM,所以选择新增一个注解让用户自己灵活的决定是否添加日志切面
2.common-log4j2-starter
1.目录结构
2.SkipLogAspect.java 自定义注解
package cn.sunxiansheng.log4j2.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Description: 跳过日志切面的注解
*
* @Author sun
* @Create 2025/1/24 18:08
* @Version 1.0
*/
@Target({ElementType.METHOD, ElementType.TYPE}) // 可以标注在类或方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
public @interface SkipLogAspect {
}
3.LogAspect.java
1.核心改动
2.完整代码
package cn.sunxiansheng.log4j2.aspectj;
import cn.sunxiansheng.log4j2.annotation.SkipLogAspect;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;
/**
* 日志切面
*
* @author sunxiansheng
*/
@Aspect
@Slf4j
public class LogAspect {
private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.create();
private static final String ANSI_RESET = "\u001B[0m";
private static final String ANSI_CYAN = "\u001B[92m";
@Pointcut("execution(public * *..controller..*(..)) || " +
"execution(public * *..service..*(..))")
public void applicationPackagePointcut() {
// 切点定义
}
@Around("applicationPackagePointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取目标类和方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Class<?> targetClass = joinPoint.getTarget().getClass();
// 检查是否存在 @SkipLogAspect 注解
if (method.isAnnotationPresent(SkipLogAspect.class) ||
targetClass.isAnnotationPresent(SkipLogAspect.class)) {
// 直接执行目标方法,不记录日志
return joinPoint.proceed();
}
// 正常记录日志逻辑
String className = signature.getDeclaringTypeName();
String methodName = signature.getName();
Object[] args = joinPoint.getArgs();
String requestParams = GSON.toJson(args);
log.info("==> 进入方法: {}.{}()", className, methodName);
log.info("参数:\n" + ANSI_CYAN + "{}" + ANSI_RESET, requestParams);
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
String response = GSON.toJson(result);
log.info("<== 退出方法: {}.{}() | 耗时: {} ms", className, methodName, endTime - startTime);
log.info("返回值:\n" + ANSI_CYAN + "{}" + ANSI_RESET, response);
return result;
}
}
3.common-log4j2-starter-demo
1.目录结构
2.TraceController.java 新增方法,测试跳过日志切面的注解
/**
* 测试跳过日志切面的注解
*
* @param msg
* @return
*/
@SkipLogAspect
@RequestMapping("/skipLogAspect")
public String skipLogAspect(String msg) {
return "skip log aspect";
}