-
Notifications
You must be signed in to change notification settings - Fork 16
十二、基于 SLF4J MDC 机制的日志链路追踪功能
ZeroOrInfinity edited this page Dec 17, 2020
·
4 revisions
- 使用此功能在日志配置文件中的
pattern
中添加%X{MDC_TRACE_ID}
即可.
<!-- 控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level ${PID:- } --- [%thread] %X{MDC_TRACE_ID} %logger[%L] - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- 只有这个日志权限才能看,sql语句 -->
<level>DEBUG</level>
</filter>
</appender>
- 自定义
SLF4J MDC
机制实现日志链路追踪 id 的类型: 可通过属性 ums.mdc.type 定义:
# 基于 SLF4J MDC 机制实现日志链路追踪 id 的类型, 默认为 uuid. 当需要自定义 id 时, type = MdcIdType.CUSTOMIZE_ID, 再实现 MdcIdGenerator.getMdcId() 方法, 注入 IOC 容器即可.
ums:
mdc:
type: UUID/THREAD_ID/SESSION_ID/CUSTOMIZE_ID
当 ums.mdc.type = CUSTOMIZE_ID 时 需要实现接口 MdcIdGenerator 并注入 IOC 容器.
- 多线程使用问题: 父线程新建子线程之前调用
MDC.getCopyOfContextMap()
方法获取MDC context
, 子线程在执行操作前先调用MDC.setContextMap(context)
方法将父线程的MDC context
设置到子线程中. ThreadPoolTaskExecutor 的配置请参考 ScheduleAutoConfiguration. - 多线程传递 MDC context 简单示例:
final Logger log = LoggerFactory.getLogger(this.getClass());
// 获取父线程 MDC 中的内容
final Map<String, String> context = MDC.getCopyOfContextMap();
final Runnable r = () -> {
log.info("testMDC");
System.out.println("...");
};
new Thread(() -> {
// 将父线程的 MDC context 设置到子线程中
MDC.setContextMap(context);
r.run();
}, "testMDC").start();