Spring Boot 3 WebFlux追踪中配置Logbook correlationId问题求助
解决思路
1. 调整Netty Handler执行顺序
问题核心是LogbookServerHandler在Sleuth创建trace span的Netty Handler之前执行,导致请求阶段无法获取traceId。只需将Logbook的Handler添加到Sleuth的Handler之后即可:
@Configuration @Slf4j @AutoConfigureBefore(LogbookWebFluxAutoConfiguration.class) public class LogbookConfig { @Bean NettyServerCustomizer nettyServerCustomizer(Logbook logbook) { return httpServer -> httpServer .doOnConnection(connection -> { // 将Logbook Handler添加到Sleuth的TracingHandler之后 connection.addHandlerAfter(new LogbookServerHandler(logbook), TracingHandler.class); // 若不清楚类名,可尝试用Sleuth Handler默认名称"tracingHandler" // connection.addHandlerAfter(new LogbookServerHandler(logbook), "tracingHandler"); }); } @Bean @Primary public CorrelationId correlationId(Tracer tracer) { return request -> { Span currentSpan = tracer.currentSpan(); if (currentSpan == null) { log.warn("当前Span为空,使用随机ID作为correlationId"); return UUID.randomUUID().toString(); } return currentSpan.context().traceId(); }; } }
2. 从Reactor Context获取TraceId(适配WebFlux非阻塞场景)
WebFlux中Sleuth会将Span信息存入Reactor Context而非ThreadLocal,直接调用tracer.currentSpan()可能因线程切换返回null。可以通过Reactor Context获取traceId:
@Configuration @Slf4j @AutoConfigureBefore(LogbookWebFluxAutoConfiguration.class) public class LogbookConfig { @Bean @Primary public CorrelationId correlationId() { return request -> { try { // 从Reactor Context中获取Span Span span = Mono.deferContextual(contextView -> Mono.justOrEmpty(contextView.getOrEmpty(Span.class)) ).block(Duration.ofMillis(100)); if (span != null) { return span.context().traceId(); } } catch (Exception e) { log.error("从Reactor Context获取traceId失败", e); } log.warn("无法获取traceId,使用随机correlationId"); return UUID.randomUUID().toString(); }; } // 禁用自定义Netty Handler,改用Logbook默认WebFilter配置 @Bean public Logbook logbook(LogbookFactory logbookFactory, CorrelationId correlationId) { return logbookFactory.create(correlationId); } }
3. 改用Logbook WebFilter替代Netty Handler
放弃自定义Netty Handler,直接使用Logbook的WebFilter实现,确保它在Sleuth的Filter之后执行:
@Configuration @Slf4j @AutoConfigureAfter(TracingWebFluxAutoConfiguration.class) // 确保在Sleuth配置后加载 @AutoConfigureBefore(LogbookWebFluxAutoConfiguration.class) public class LogbookConfig { @Bean @Primary public CorrelationId correlationId(Tracer tracer) { return request -> { Span currentSpan = tracer.currentSpan(); return currentSpan != null ? currentSpan.context().traceId() : UUID.randomUUID().toString(); }; } @Bean public LogbookWebFilter logbookWebFilter(Logbook logbook, HttpMessageWriter<?> writer) { return new LogbookWebFilter(logbook, writer); } }
此时WebFilter会在Sleuth创建好trace span后再执行,调用tracer.currentSpan()即可拿到正确的traceId。
内容的提问来源于stack exchange,提问作者Pablo
相关产品推荐
相关产品推荐

