美文网首页
通过MDC实现多线程链路跟踪

通过MDC实现多线程链路跟踪

作者: 小心我的code | 来源:发表于2021-09-15 19:56 被阅读0次

查找日志的时候大家可能会有感受,由于日志打印一般是无序的,多线程下想要拿到一次请求中的相关日志简直是大海捞针。亦或者多系统间相互调用的时候如何快速找到某次请求的链路,MDC的出现就是解决当前问题很好的选择。

SLF4J的MDC

SLF4J 提供了MDC ( Mapped Diagnostic Contexts )功能,它的实现也是利用了 ThreadLocal 机制。 在代码中,只需要将指定的值 put 到线程上下文的 Map 中,然后在对应的地方使用 get 方法获取对应的值,从而达到自定义和修改日志输出格式内容的目的。目前只有log4j和logback提供原生的MDC支持。

应用方法

  • 创建Interceptor或者filter。拦截所有请求,在处理请求前将TRACE_ID放到MDC中,在处理完请求后清除MDC的内容。
public class LoggingInterceptor implements HandlerInterceptor {
    public static final String PROJECT_NAME = "PANACEA-";

    private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        MDC.put(MDCKeys.REQUEST_URI, request.getRequestURI());
        MDC.put(MDCKeys.REQUEST_METHOD, request.getMethod());
        MDC.put(MDCKeys.TRACE_ID, TraceIdGenerator.nextTraceId(PROJECT_NAME));

        logger.info("LoggingInterceptor.preHandle,request:",request);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.info("LoggingInterceptor.afterCompletion");
        MDC.clear();
    }
}
  • 注册Interceptor
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/**");
    }
}
  • 设置日志输出格式,日志文件添加对应的MDC变量值
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--  格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符  -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%n [%-5level][%d{yyyy-MM-dd HH:mm:ss.SSS}] 
                *******[%mdc{TRACE_ID}] [%thread] [%mdc{REQUEST_URI}] *****
                %msg [%file:%line] %logger{35}%n</pattern>
        </layout>
    </appender>

以上!

相关文章

网友评论

      本文标题:通过MDC实现多线程链路跟踪

      本文链接:https://www.haomeiwen.com/subject/ubrlgltx.html