我正在尝试开放式遥测自动检测。但使用 CompletableFuture.handle 时,跟踪似乎丢失了。有人可以帮我解决这个问题吗?
@GetMapping("/future3")
public CompletableFuture<ResponseEntity<String>> future3() {
LOGGER.info("future1 "); // <- we have trace here
LOGGER.info("trace={}", Span.current().getSpanContext().getTraceId()); // <- we have trace here
SqsAsyncClient sqsAsyncClient = SqsAsyncClient.builder().build();
CompletableFuture<ResponseEntity<String>> aa = sqsAsyncClient
.sendMessage(build -> build.queueUrl(queueUrl).messageBody("hello"))
.handle((response, error) -> {
LOGGER.info("trace response={}", Span.current().getSpanContext().getTraceId()); // <- we lost trace
LOGGER.info("test response={}", response); // <- we lost trace
return new ResponseEntity<>("success", HttpStatus.OK);
});
LOGGER.info("future1_1"); // <- we have trace id
return aa;
}
我确实遇到了同样的问题,幸运的是我可以从您的代码中为您提供解决方案,我发现您在使用 CompletableFuture.handle 时丢失跟踪上下文时遇到的问题。作为一种解决方案,我建议您可以使用 Context,或者我认为 Span 是 OpenTelemetry 显式传播功能的一个不错选择,以确保跟踪上下文传播到异步回调中。 因此,首先,Context 可以捕获并显式传递给异步任务,对我来说,我建议在方法的开头捕获当前的 Context,然后在 .handle 方法中使用这个捕获的上下文
我也对代码进行了一些修改,以帮助您获得快速的产品,这就是代码:
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
@GetMapping("/future3")
public CompletableFuture<ResponseEntity<String>> future3() {
LOGGER.info("future1 ");
LOGGER.info("trace={}", Span.current().getSpanContext().getTraceId());
SqsAsyncClient sqsAsyncClient = SqsAsyncClient.builder().build();
// 捕获当前的 OpenTelemetry 上下文
Context currentContext = Context.current();
CompletableFuture<ResponseEntity<String>> aa = sqsAsyncClient
.sendMessage(build -> build.queueUrl(queueUrl).messageBody("hello"))
.handle((response, error) -> {
// 使 OpenTelemetry 上下文在此句柄块中成为当前上下文
try (Scope scope = currentContext.makeCurrent()) {
LOGGER.info("trace response={}", Span.current().getSpanContext().getTraceId());
LOGGER.info("test response={}", response);
return new ResponseEntity<>("success", HttpStatus.OK);
}
});
LOGGER.info("future1_1");
return aa;
}
所以这就是我所能提供的帮助,希望它能起作用。 祝你好运😉🙏