Spring Cloud Sleuth在JBoss EAP中运行时日志缺失Trace与Span信息
我之前处理过好几起类似JBoss EAP与Spring Cloud Sleuth集成的日志问题,你的推测完全正确——核心原因就是JBoss EAP自带的日志框架没有正确读取SLF4J MDC(Mapped Diagnostic Context)中的Trace/Span ID信息。下面是几个经过验证的解决方案:
1. 调整JBoss EAP日志配置,启用MDC读取
JBoss EAP默认使用JBoss Logging框架,它虽然兼容SLF4J,但默认不会主动读取MDC中的自定义字段(比如Sleuth的traceId、spanId)。你需要修改EAP的配置文件(standalone.xml或domain.xml),修改日志输出格式并启用MDC支持:
找到日志子系统的配置段(urn:jboss:domain:logging开头),调整对应的handler(比如console-handler或file-handler)的pattern:
<console-handler name="CONSOLE"> <level name="INFO"/> <formatter> <named-formatter name="PATTERN"/> </formatter> </console-handler> <named-formatter name="PATTERN"> <pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%X{spring.application.name},%X{traceId},%X{spanId},%X{exportable}] %s%e%n</pattern> </named-formatter>
这里的%X{key}就是从MDC中读取对应键值的语法,正好匹配Sleuth自动放入MDC的四个字段:
spring.application.name:对应你日志里的identitytraceId:Sleuth生成的全局跟踪IDspanId:当前请求的Span IDexportable:是否要导出到Zipkin等工具的标识
2. 替换EAP日志绑定,强制使用SLF4J+Logback
如果修改EAP配置不方便,你可以让应用完全使用SLF4J+Logback,绕过JBoss自带的日志框架。步骤如下:
- 在项目的
src/main/resources下创建jboss-deployment-structure.xml,排除EAP自带的日志模块:
<jboss-deployment-structure> <deployment> <exclusions> <module name="org.jboss.logging"/> <module name="org.slf4j"/> <module name="org.slf4j.impl"/> </exclusions> </deployment> </jboss-deployment-structure>
- 在
pom.xml中引入Logback依赖,并确保Spring Boot排除其他日志框架:
<dependencies> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
这样应用就会用Logback处理日志,而Logback默认会读取SLF4J的MDC,Sleuth的Trace信息就能正常输出了。
3. 验证Sleuth的MDC填充是否生效
在排查时,你可以先在代码中手动打印MDC的值,确认Sleuth是否正确填充了Trace信息:
import org.slf4j.MDC; // 在请求处理的代码中添加 System.out.println("Trace ID: " + MDC.get("traceId")); System.out.println("Span ID: " + MDC.get("spanId"));
如果打印结果是null,说明Sleuth的Trace拦截器没有在EAP的线程上下文中生效,你需要检查:
- 是否开启了
spring.sleuth.web.enabled=true(默认是开启的,但可以显式配置) - 应用是否正确扫描到了Sleuth的自动配置类
- EAP的线程池是否拦截了请求,导致MDC上下文没有传递
内容的提问来源于stack exchange,提问作者cambierr

