Logback 系列(12):高级篇 · MDC 链路追踪

本系列第 12 篇。一次请求跨多个方法,日志散在各处,靠 traceId 串起来。这就是 MDC 的用武之地。

MDC 是什么

MDC(Mapped Diagnostic Context)是一个线程级的 Map ,你放进去的键值对,会在这个线程后续所有日志里自动可用。最典型的用法就是 traceId

基本用法

java 复制代码
import org.slf4j.MDC;

// 请求入口(拦截器 / Filter)放入
MDC.put("traceId", UUID.randomUUID().toString());
try {
    // ...业务处理,期间所有日志都自动带上 traceId
} finally {
    MDC.clear();   // 一定要清,否则线程池复用会串味
}

Pattern 里输出

xml 复制代码
<pattern>%d [%thread] %-5level %X{traceId} %logger - %msg%n</pattern>

%X{traceId} 就会取出 MDC 里的 traceId。这样同一次请求的所有日志都带同一个 id,在日志平台里一搜就能看到完整链路。

最大的坑:跨线程不传递

MDC 底层是 ThreadLocal跨线程/线程池不会自动传递。当你用了:

  • @Async 异步方法
  • 线程池 ExecutorService
  • CompletableFuture

子线程里的日志会丢失 traceId

解决办法

  1. 阿里 TransmittableThreadLocal(TTL) :专门解决线程池间 ThreadLocal 传递,配合 TtlExecutors 包装线程池即可。
  2. 手动传递 :提交任务前取出 MDC,在子线程开头 MDC.setContextMap(...),结束时清理。

实战建议

  • 在网关或 Filter 统一生成 traceId,若上游已带(如 HTTP header)则复用,实现跨服务链路串联。
  • 记得 finallyMDC.clear(),线程池场景尤其重要,否则会"串味"------A 请求的 traceId 出现在 B 请求日志里。

上一篇:接入日志平台

下一篇:生产环境配置建议清单

相关推荐
倒流时光三十年1 天前
Logback 系列(13):生产环境配置建议清单
logback
倒流时光三十年2 天前
Logback 系列(3):三大核心组件 Logger / Appender / Encoder
java·开发语言·logback
倒流时光三十年2 天前
Logback 系列(7):常用 Appender(控制台 / 文件 / 滚动文件)
java·前端·logback
倒流时光三十年2 天前
Logback 系列(6):Pattern 布局语法速查
logback
我是唐青枫5 天前
Java SLF4J 实战指南:从日志门面到 Logback、MDC 和链路追踪
java·开发语言·logback
豆瓣鸡14 天前
整合Logback日志框架
logback
逆光的July1 个月前
Logback 学习笔记
笔记·学习·logback
大大杰哥2 个月前
Java 日志框架详解:SLF4J + Logback 从入门到实战
java·开发语言·logback
RemainderTime2 个月前
(十二)Spring Cloud Alibaba 2023.x:基于 Filebeat 构建轻量级 ELK日志追踪体系
分布式·elk·elasticsearch·微服务·架构·logback