雷迪森俺的杰特们,日志查询不管在测试环境或是生产环境,都是作为一个开发人员经常要去找、要去看的东西。某个业务出现BUG,那么如何迅速的定位我们所要找的日志及相关的其它日志?事关测试及开发人员定位问题的效率,往往大家都是根据自己打印的日志的关键字去查询日志,但是在并发量大、或业务流程长导致日志不连贯的场景中往往你无法通过一次、两次的日志查询看清整个业务线的日志。甚至只能通过去看实时日志 然后重现,才能看清问题。然而生产环境中很多时候哪会给你重现的机会,同时现在分布式微服务大力推行,一旦调用其他服务出了BUG 是不是又要重新去找关键字查日志?
问题来了,为什么这么麻烦大家还不去优化?咱打印日志弄的像京东购物一样,弄个订单号本次请求的所有日志都带上该订单号,后台每一次的响应都带上日志订单号,或者只要抛异常就带上日志订单号返回至前端。然后找日志直接查订单号不就可以了吗? 测试人员拿着日志ID 交给开发 哪还需要复现?效率提高10倍 有没有?完美 有了方案 咱就去干!
第一步 当然是拦截所有的HTTP请求给每个请求所产生的日志都加上一个唯一标识。
引入maven依赖
新建过滤器MdcFilter 继承 MDCInsertingServletFilter
Logback自带的ch.qos.logback.classic.helpers.MDCInsertingServletFilter能够将HTTP请求的hostname, request URI, user-agent等信息装入MDC
spring 注解小课堂开课啦
- @Configuration 表示该类为spring配置类
- @ConditionalOnClass 判断某个类是否存在于 classpath 中两个一起用就是 当classpath 中存在org.springframework.web.servlet.DispatcherServlet 就加载MdcFilterAutoConfigure
- @Bean 产生一个Bean,然后交给Spring容器管理。@Configuration与@Bean结合使用。@Configuration可理解为用spring的时候xml里面的<beans>标签,@Bean可理解为用spring的时候xml里面的<bean>标签
- @ConditionalOnMissingBean 当指定的Bena不存在时返回true,结合@Bean使用就是如果容器中MdcFilter不存在咱们就产生一个MdcFilter交给spring
日志链路ID生成工具类
日志链路ID存储、与销毁工具类
主要适用于调用dubbo接口时候取出TraceId且做到保证子线程也能拿到TraceId,其实如果不涉及跨系统的接口调用这个类是没有存在的必要的。
logback.xml设置日志输出格式
<pattern> 属性配置:(贴出我配置的格式 [%X{traceId}] 这个就是线程ID了)
[%-5level] [%contextName] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{req.remoteHost}] [%X{req.requestURI}] [%X{traceId}] %logger - %msg%n
到这里整个日志链路追踪完成了一半,已经可以做到所有HTTP的请求都给加上traceId,但是如果我们调用dubbo接口,MdcFilter 是无法拦截的,所以导致logback中找不到traceId,所以我们需要再加一个com.alibaba.dubbo.rpc.Filter用于守好dubbo的消费者和服务提供者的门,消费者需要交出自己的traceId,服务提供者收到请求将traceId摄入。
详见我的上一篇博客:Dubbo之Filter过滤器(拦截器)的使用
比较懒 这里我就不做过多的描述了 抱歉。
当你完成这一步之后整个日志链路系统基本就完成了90% 如果你足够努力,同时把EFK弄起来 查询日志效率直接一步登天
- 名词解析 EFK
通过filebeat实时收集 nginx访问日志 ▷ filebeat将收集的日志传输至elasticsearch集群 ▷ 通过kibana展示日志。
但是会思考的同学就会问了,老夫的定时任务执行报错了还不一样日了狗,日志里面的traceId是null的啊。
说白了上面的方法还是只搞定外部发起的请求 程序自己的定时任务咋整呢?
这时候面试常出现的问题AOP 浮出水面。
AOP有需要了解的同学可以进传送门: 轻松实现aop功能的三种方式
新建拦截器
注解小课堂又开课啦:错误日志找不到,多半是太懒,打一顿就好
- @ConditionalOnProperty 当可以读取到指定name的配置时为true,如果还配置了value属性,那就要比对配置的值要和指定的value一样才是true。