文章目录
-
- 1.common-log4j2-starter
-
-
- 1.目录
- [2.pom.xml 引入依赖](#2.pom.xml 引入依赖)
- 3.LogAspect.java
- [4.Log4j2AutoConfiguration.java Log4j2自动配置类条件注入切面类](#4.Log4j2AutoConfiguration.java Log4j2自动配置类条件注入切面类)
-
- [2.common-log4j2-starter-demo 测试](#2.common-log4j2-starter-demo 测试)
-
-
- 1.目录
- [2.application.yml 启用日志切面](#2.application.yml 启用日志切面)
- 3.TraceController.java
- 4.结果
-
1.common-log4j2-starter
1.目录
2.pom.xml 引入依赖
xml
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
3.LogAspect.java
java
package com.sunxiansheng.log4j2.aspectj;
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.*;
import org.aspectj.lang.reflect.MethodSignature;
@Aspect
@Slf4j
public class LogAspect {
// 使用 Gson 序列化对象,启用 PrettyPrinting,输出格式化的 JSON
private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting() // 启用格式化输出
.disableHtmlEscaping() // 禁用 HTML 转义,保留字符原始形式
.create();
// ANSI 颜色代码
private static final String ANSI_RESET = "\u001B[0m"; // 重置颜色
private static final String ANSI_CYAN = "\u001B[92m"; // 绿色
/**
* 配置切点,匹配 Controller 和 Service 层的所有方法
*/
@Pointcut("execution(* com.sunxiansheng..controller..*(..)) || execution(* com.sunxiansheng..service..*(..))")
public void applicationPackagePointcut() {
// 方法为空,这是一个切点定义
}
/**
* 环绕通知,记录方法执行的详细信息
*
* @param joinPoint 切入点
* @return 方法执行结果
* @throws Throwable 异常
*/
@Around("applicationPackagePointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法签名和详细信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
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;
try {
// 执行目标方法
result = joinPoint.proceed();
} catch (Throwable throwable) {
// 捕获并记录异常信息,堆栈信息从下一行开始输出
String exceptionStackTrace = getStackTraceAsString(throwable);
log.error("<== 方法异常: {}.{}() | 异常信息: {}", className, methodName, throwable.getMessage());
log.error("堆栈信息:\n{}", exceptionStackTrace);
throw throwable; // 重新抛出异常,保持原有异常机制
}
// 记录方法执行结束时间
long endTime = System.currentTimeMillis();
long executionTime = endTime - startTime;
// 获取方法返回值
String response = GSON.toJson(result);
// 记录方法退出日志,返回值从下一行开始输出,返回值部分以黄色显示
log.info("<== 退出方法: {}.{}() | 耗时: {} ms", className, methodName, executionTime);
log.info("返回值:\n" + ANSI_CYAN + "{}" + ANSI_RESET, response);
return result;
}
/**
* 将异常的堆栈信息转换为字符串
*
* @param throwable 异常
* @return 堆栈信息字符串
*/
private String getStackTraceAsString(Throwable throwable) {
StringBuilder sb = new StringBuilder();
for (StackTraceElement element : throwable.getStackTrace()) {
sb.append("\tat ").append(element.toString()).append("\n");
}
return sb.toString();
}
}
4.Log4j2AutoConfiguration.java Log4j2自动配置类条件注入切面类
java
package com.sunxiansheng.log4j2.config;
import com.sunxiansheng.log4j2.aspectj.LogAspect;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Description: Log4j2自动配置类
*
* @Author sun
* @Create 2024/10/24 10:36
* @Version 1.0
*/
@Configuration
public class Log4j2AutoConfiguration {
/**
* 条件注入LogAspect
*
* @return
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "log.aspect.enable", havingValue = "true", matchIfMissing = true)
LogAspect logAspect() {
return new LogAspect();
}
}
2.common-log4j2-starter-demo 测试
1.目录
2.application.yml 启用日志切面
yaml
log:
aspect:
enable: true # 开启自定义的日志切面
3.TraceController.java
java
/**
* 测试的Bean,入参
*/
@Data
static class AspectBeanIn {
private String name;
private Integer age;
private String phone;
}
/**
* 测试的Bean,出参
*/
@Data
static class AspectBeanOut {
private String name;
private Integer age;
private String phone;
}
@RequestMapping("/aspect")
public AspectBeanOut aspect(@RequestBody AspectBeanIn aspectBeanIn) {
AspectBeanOut aspectBean = new AspectBeanOut();
aspectBean.setName("sun");
aspectBean.setAge(18);
aspectBean.setPhone("123456789");
// 出现异常
int i = 1 / 0;
return aspectBean;
}