SpringBoot 3中如何在每条日志中正确打印TraceId和SpanId
SpringBoot 3中如何在每条日志中正确打印TraceId和SpanId
我完全懂你这种升级后的困惑!从Spring Boot旧版本依赖Spring Cloud Sleuth自动注入TraceId/SpanId到MDC,到Spring Boot 3.x切换到Micrometer Tracing后日志突然失效,确实容易踩坑。而且你提到的Observation机制看起来有大量冗余操作,自己写的Handler处理所有Observation显得浪费,这其实是因为你没用到官方提供的开箱即用方案,还踩了MDC键名变更的坑。
问题根源
- MDC键名默认变更:Spring Cloud Sleuth使用
X-B3-TraceId/X-B3-SpanId作为MDC存储键,而Micrometer Tracing默认改用小写的traceId/spanId。如果你的logback.xml还沿用旧键名,自然拿不到日志变量值。 - 自定义Handler的冗余处理:你自己实现的
MdcObservationHandler的supportsContext返回true,导致它会处理所有21个Observation(包括每个过滤器、链路环节的观测),这才是你觉得“大量无用工作”的核心原因——官方的MDC处理器只会针对链路追踪相关的Observation触发,不会无差别处理所有观测。
正确的解决方案(无需自定义Handler)
1. 精简依赖配置
你不需要单独引入micrometer-tracing,因为micrometer-tracing-bridge-brave已经包含了该依赖,最终依赖可以简化为:
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-tracing-bridge-brave</artifactId> </dependency>
2. 适配日志配置的MDC键名
有两种方式适配:
- 方式一:修改logback配置(推荐)
把logback.xml中的旧键名替换为Micrometer Tracing默认的键:%X{traceId:-},%X{spanId:-},%X{spanExportable:-} - 方式二:开启X-B3键名兼容(保留原有logback配置)
通过配置文件让Micrometer Tracing同时写入旧的X-B3键名,无需修改logback:
或YAML格式:management.tracing.mdc.keys=X-B3-TraceId,X-B3-SpanId,X-Span-Exportmanagement: tracing: mdc: keys: X-B3-TraceId,X-B3-SpanId,X-Span-Export
3. 移除自定义ObservationConfig
Micrometer Tracing会自动注册官方的MdcObservationHandler,它只会处理链路追踪相关的Observation,性能更优。你可以完全删除自己编写的ObservationConfig类,无需手动注册处理器。
特殊场景下的自定义处理(不推荐)
如果因为业务特殊需求必须自定义Observation Handler,一定要在supportsContext中过滤出仅链路相关的观测,避免冗余操作:
@Override public boolean supportsContext(Observation.Context context) { // 仅处理包含TraceContext的链路追踪观测 return context.getOrDefault(TraceContext.class, null) != null; }
内容来源于stack exchange




