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

查找日志的时候大家可能会有感受,由于日志打印一般是无序的,多线程下想要拿到一次请求中的相关日志简直是大海捞针。亦或者多系统间相互调用的时候如何快速找到某次请求的链路,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>

以上!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容