AOP、MDC实现日志追踪
前言
- 在实际开发中,日志输出是非常重要的,在生产环境中,如果 日志打得好,可以快速地排查问题,为了更好的查看日志,我们需要将这些日志串联起来,这样会使排查问题变得更加轻松。正好我前一篇文介绍了ELK的搭建,那么现在我们再来看看AOP+MDC如何实现日志追踪。
- 如果我们可以在日志中记录用户的IP,那么我们就能分析该用户的所有操作日志。如果我们可以在日志中记录订单ID,那么如果我们的订单出现了问题,我们可以很快的来根据订单ID在Kibana中搜索与该订单ID关联的所有日志信息。
实现思路
- 串联的核心在于要把ID作为一个请求必传参数,例如我们手动打印日志的时候,可以在日志中加上我们的业务ID,例如
1 | log.info("提交订单开始:{}", orderId); |
- 但是此种方式较为繁琐,我们需要在每条日志中都手动加上orderId的输出,那么有没有更简单的方式呢?首先想到的是AOP,因为AOP可以将日志记录的行为从业务的核心逻辑中分离出来,而MDC是一个线程安全的存放诊断日志的容器,在处理请求前将请求的唯一标示放到MDC容器中,这个唯一标示会随着日志一起输出,以此来区分该条日志是属于那个请求的。并在请求处理完成之后清除MDC容器。
1 | public interface MDCAdapter { |
- Logback配置:使用MDC机制,我们需要在logback.xml日志模板中进行一些配置,通过使用占位符
%X{}
来占位,替换到对应MDC中key的值。
1 | value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([${springAppName:-}]){yellow} %clr(%X{TRACE_ID}){cyan} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %green([%X{userIp}]) %cyan([%X{requestURI}]) %green([%X{orderId}]) %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" |
- 我们可以通过拦截器,将用户IP信息记录到日志中
1 |
|
MDC结合AOP
- 因为这部分其实是半道里加进来的,所以写的比较粗糙,但是实现思路就是用切点表达式来匹配订单相关信息,主要就是Order这个实体类和orderId这个参数,但是切点不支持匹配参数名,所以匹配String orderId的时候会比较麻烦,需要一个一个手动匹配(因为不支持参数名匹配,按类型匹配会匹配第一个参数是Sting的方法,所以会匹配错)。
- 我这里的建议是通过方法名进行匹配,那么就需要订单相关的方法名的后缀进行统一,然后切点表达式按方法名后缀匹配就好了
(后期有空再重构重构代码吧,毕竟这里写的实在不太好)
1 |
|
评论