Spring Boot中通过AOP实现统一日志解决方案

本文介绍了如何在Spring Boot应用中利用AOP和logback实现日志的统一处理。通过创建logback配置文件,设置不同环境的日志级别,并定义自定义注解@Log,配合切面类记录方法的执行信息,如方法名、参数、返回值和耗时。这种做法避免了代码中重复的日志代码,提高了代码的可维护性。

日志是整个系统中非常重要的一环,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非常简单~
再也不需要在每个类和方法里都引入日志代码,解耦了代码,方便了维护。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值