使用 CompletableFuture 时不会传播跟踪上下文

问题描述 投票:0回答:1

以下测试无法正常工作

@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 文档非常差。我是不是误会了什么?

这个想法是保留跟踪上下文以允许将其转发到下一层,包括行李......

spring-boot micrometer spring-micrometer micrometer-tracing
1个回答
0
投票

您可以使用

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.