日志是整个系统中非常重要的一环,JAVA中也有很多日志框架,本文实现了在Spring Boot中利用logback和aop统一处理日志。本文比较简单,已记录为主O(∩_∩)O~
首先在resources目录下新建logback-spring.xml作为logback的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<property name="LOG_HOME" value="/data/log" />
<!--<property name="LOG_HOME" value=" D:/data/log" />-->
<!--写入日志到控制台的appender,用默认的,但是要去掉charset,否则windows下tomcat下乱码-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
<appender name="StackRollingFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_HOME}/vcash-order.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/vcash-order.%d{yyyy-MM-dd}.log</FileNamePattern>
<!-- 最多保存60day日志文件 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<Pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg %n</Pattern>
</encoder>
</appender>
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
<appender-ref ref="StackRollingFileAppender" />
</root>
</springProfile>
<springProfile name="test">
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="StackRollingFileAppender" />
</root>
</springProfile>
<springProfile name="prd">
<root level="INFO">
<appender-ref ref="StackRollingFileAppender" />
</root>
</springProfile>
</configuration>
可以看到,通过LOG_HOME这个property指定了日志存放的路径
通过springProfile指定了3种不同的环境,分别对应开发、测试和生产环境,在这里面指定了日志级别,并且引用了上面定义的两个appender
新建一个注解@Log:
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}
新建一个aspect类,在该类中处理日志的记录:
@Aspect
@Component
public class VBSAspect {
private static final Logger log= LoggerFactory.getLogger(VBSAspect.class);
@Pointcut("@annotation(com.vcash.wechat.annotation.Log)")
public void logPointcut(){}
@Around("logPointcut()")
public Object logHandler(ProceedingJoinPoint process) throws Throwable{
long startTime=System.currentTimeMillis();
MethodSignature methodSignature= (MethodSignature) process.getSignature();
Method method=methodSignature.getMethod();
String methodName=method.getName();
String className= method.getDeclaringClass().getName();
Object[] args=process.getArgs();
StringBuilder params=new StringBuilder();
for (int i = 0; i < args.length; i++) {
params.append(args[i].toString());
params.append(";");
}
Object result= null;
try {
result = process.proceed();
} catch (Throwable throwable) {
String exception=throwable.getClass()+":"+throwable.getMessage();
long costTime=System.currentTimeMillis()-startTime;
log.error("请求时间:{},请求耗时:{},请求类名:{},请求方法:{},请求参数:{},请求结果:{}",startTime,costTime,className,methodName,params.toString(),exception);
return CustomerResponse.buildFail(throwable.getMessage());
}
long costTime=System.currentTimeMillis()-beginTime;
log.info("请求时间:{},请求耗时:{},请求类名:{},请求方法:{},请求参数:{},请求结果:{}",startTime,costTime,className,methodName,params.toString(), result);
return result;
}
}
可以看到,@Pointcut里指定了需要切入的地方为注解@Log存在的地方,而@Log又是注解在方法上的,所以在logHandler方法里,获取了@Log所注解方法的一系列参数,比如方法名、入参、出参、耗时等,并将这些参数以特定的格式写入日志,当然,你也可以在这里把日志写到数据库。
以上,就完成了整个系统里的日志处理,484非常简单~
再也不需要在每个类和方法里都引入日志代码,解耦了代码,方便了维护。
本文介绍了如何在Spring Boot应用中利用AOP和logback实现日志的统一处理。通过创建logback配置文件,设置不同环境的日志级别,并定义自定义注解@Log,配合切面类记录方法的执行信息,如方法名、参数、返回值和耗时。这种做法避免了代码中重复的日志代码,提高了代码的可维护性。
1870

被折叠的 条评论
为什么被折叠?



