以下测试无法正常工作
@Test
void testContextPropagation() throws ExecutionException, InterruptedException {
// create a new trace using the micrometer tracer coming from the Spring Boot context
ScopedSpan scopedSpan = tracer.startScopedSpan("trigger the creation of a new trace...");
logger.info("CONTEXT: {}", tracer.currentTraceContext().context());
CompletableFuture.supplyAsync(() -> {
logger.info("CONTEXT: {}", tracer.currentTraceContext().context());
return null;
}, ContextSnapshotFactory.builder().build().captureAll().wrapExecutor(Executors.newSingleThreadExecutor())).get();
scopedSpan.end();
}
该测试的输出将是
CONTEXT: 661e6f0f5965abb6cb8ddf9d107eea2c/cb8ddf9d107eea2c
CONTEXT: null
虽然应该如此
CONTEXT: 661e6f0f5965abb6cb8ddf9d107eea2c/cb8ddf9d107eea2c
CONTEXT: 661e6f0f5965abb6cb8ddf9d107eea2c/cb8ddf9d107eea2c
预期的行为是将跟踪上下文保留到 CompletableFuture 中,但事实并非如此。
Spring Boot版本:3.2.4
非常欢迎有关该主题的任何帮助。关于跟踪的 Spring Boot 和 micrometer 文档非常差。我是不是误会了什么?
这个想法是保留跟踪上下文以允许将其转发到下一层,包括行李......
ContextExecutorService
(或 ContextScheduledExecutorService
)使用 CompletableFuture
自动传播跟踪信息,但您需要将该执行器传递给 CompletableFuture
(请参阅其 javadoc):
ContextExecutorService.wrap(Executors.newSingleThreadExecutor());
您可能需要注册一个访问器:
ContextRegistry.getInstance().registerThreadLocalAccessor(...);
如果由于某种原因您无法执行此操作,则需要手动执行此操作,请参阅此问题:context-propagation#138或检查我们执行此操作的测试之一:
CurrentObservationTest
:
@Test
void testManualContextPropagation() throws Exception {
Span newSpan = this.tracer.nextSpan().name("test").start();
try (SpanInScope ignored = this.tracer.withSpan(newSpan)) {
System.out.println("CONTEXT: " + tracer.currentSpan().context());
}
CompletableFuture.runAsync(() -> {
try (SpanInScope ignored = this.tracer.withSpan(newSpan)) {
System.out.println("CONTEXT: " + tracer.currentSpan().context());
}
finally {
newSpan.end();
}
}).get();
}