如何在 Spring Reactor 上下文中访问当前跨度和跟踪 ID?

How do I access the current span and trace ids in a Spring Reactor context?

在我的 Spring Boot WebFlux 应用程序中,我使用的是 Reactor。我已设置 spring.sleuth.reactor.instrumentation-type=manual 并在服务方法上使用 @ContinueSpan。我从代码中看到,span 是以反应方式适当地创建、开始和结束的。

后面需要在Flux中提取trace信息

我正在使用的代码注入了 Tracer,我使用 Tracer.currentSpan().context() 来尝试获取跟踪上下文。我可以成功获取 currentSpan() 直到我调用 R2DBC 存储库方法,之后 currentSpan 为空。我可以通过注释存储库方法使跨度成为“当前”,但除非必要,否则我不想这样做。我想了解潜在的“问题”。

我还查看了 Reactor 订阅上下文中的 CurrentTraceContext,发现它的回答与 Tracer 一样。支持两者似乎是线程本地支持的跟踪上下文。

奇怪的是,如果我在订阅者上下文中查看 TraceContext,跟踪、父级和跨度 ID 都在那里。 WebFluxSleuthOperators.currentTraceContext(Context...) 似乎是这样做的 - 所以我不得不相信这是获取跟踪上下文的合适工具。

那么,几个问题:

  1. WebFluxSleuthOperators.currentTraceContext(上下文...) [反应堆订阅上下文中的 TraceContext] 是获取最新跟踪上下文的正确方法吗?

  2. 查看 ReactorSleuthMethodInvocationProcessor,将对当前跨度和跟踪上下文的引用提供给 SpanSubscriber,将它们放入订阅者上下文中。如前所述,subscribe() 和 next() 是在该跨度的上下文中调用的。为什么诸如调用 r2dbc 存储库方法之类的方法会有效地“擦除”tracer.currentSpan() 但单独留下跟踪上下文?

我很想更深入地理解这一点,并会更多地查看源代码。但是现在任何见解都非常感谢。非常感谢您。

要在 Spring 中访问 Reactor 流中的当前跨度,请使用在订阅者上下文中找到的 Span 或 TraceContext。

Mono.deferContextual(contextView -> Mono.just(contextView.get(TraceContext.class)))

或者,更好的是,使用 WebFluxSleuthOperators.currentTraceContext(Context.of(contextView)))

通过 Tracer bean 访问跨度可能不会产生当前跨度 - 因为当前线程可能与发起跨度并将其带入范围的线程不同。通过调试证实了这一点。