Reputation: 291
The following test is not working as it should
@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();
}
The ouptut of this test will be
CONTEXT: 661e6f0f5965abb6cb8ddf9d107eea2c/cb8ddf9d107eea2c
CONTEXT: null
while it should be
CONTEXT: 661e6f0f5965abb6cb8ddf9d107eea2c/cb8ddf9d107eea2c
CONTEXT: 661e6f0f5965abb6cb8ddf9d107eea2c/cb8ddf9d107eea2c
The expected behaviour would be to keep the trace context into the CompletableFuture but this is not the case.
Spring Boot version: 3.2.4
Any help on that topic is more than welcome. The Spring Boot and micrometer documentation around tracing is quite poor. Did I misunderstand something?
The idea would be to keep the tracing context to allow forwarding it to the next layers, including baggages...
Upvotes: 0
Views: 1206
Reputation: 6931
You can use ContextExecutorService
(or ContextScheduledExecutorService
) to automatically propagate tracing information using CompletableFuture
but you need to pass that executor to CompletableFuture
(see its javadoc):
ContextExecutorService.wrap(Executors.newSingleThreadExecutor());
and you might need to register an accessor:
ContextRegistry.getInstance().registerThreadLocalAccessor(...);
If you cannot do this for some reason, you need to do it manually, see this issue: context-propagation#138 or check one of our tests that does this: 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();
}
Upvotes: 2