配置Apache Camel 4.1.0实现Trace ID与Span ID打印及路由传递
问题现象
使用Apache Camel 4.1.0集成OpenTelemetry,已添加依赖、启用MDC日志并完成配置,但调用路由时日志中的Trace ID和Span ID均显示为全0值,无法实现跨路由的Trace/Span传递与打印。
日志示例:
INFO [service,00000000000000000000000000000000,0000000000000000] 476 --- [14 - Aggregator] eamRoute : Total time taken for batch insertion: 0 seconds
INFO [payment-service,00000000000000000000000000000000,0000000000000000] 476 --- [ormAndSendRoute] message-producer : Request body sending to API:
已完成的配置
添加依赖
<dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-opentelemetry-starter</artifactId> <version>${camel.version}</version> </dependency>
application.yml配置
springboot: main-run-controller: true use-mdc-logging: true mdc-logging-keys-pattern: "*" logging: file: name: '${logging.file.path}/app.log' path: ./logs pattern: level: "%5p [${spring.application.name:},%X{trace_id:-},%X{span_id:-}]"
Spring Boot代码
@SpringBootApplication @CamelOpenTelemetry public class TraceIdApplication { public static void main(String[] args) { SpringApplication.run(TraceIdApplication.class, args); } } @Component public class CamelTraceId extends RouteBuilder { @Override public void configure() throws Exception { from("timer://foo?fixedRate=true&delay=0&period=2000") .log("in timer") .to("direct:traceLogging") .end(); from("direct:traceLogging") .to("direct:restfulcall") .log("testing").end(); } }
解决方案
1. 修正MDC日志键名匹配
Camel的OpenTelemetry集成在MDC中注入的Trace/Span键名为traceId和spanId,而非配置中的trace_id和span_id。修改日志pattern:
logging: pattern: level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
2. 显式启用OpenTelemetry并配置采样策略
在application.yml中添加OpenTelemetry相关配置,确保采样策略为全采样,避免因采样率为0导致无Trace/Span生成:
camel: opentelemetry: enabled: true tracing-mode: active # 主动追踪所有路由节点 otel: traces: sampler: always_on # 全采样,确保所有请求生成Trace/Span
3. 确保路由操作被Span覆盖(可选)
对于Timer这类定时触发的组件,可显式在路由中开启Span,确保追踪生效:
@Override public void configure() throws Exception { from("timer://foo?fixedRate=true&delay=0&period=2000") .startSpan("timer-init-span") // 显式启动根Span .log("in timer") .to("direct:traceLogging") .end(); from("direct:traceLogging") .startSpan("trace-logging-span") // 启动子Span .to("direct:restfulcall") .log("testing") .end(); }
验证结果
重启应用后,日志中应显示正常的非全0 Trace ID和Span ID,且跨路由调用时Trace ID保持一致,Span ID随路由节点切换。
内容的提问来源于stack exchange,提问作者Charan

