解决代码使用CompletableFuture做异步时spring-cloud-starter-sleuth的日志追踪号为空的情况
产生问题原因
就是异步调用,导致spanId和traceId丢失了
@Async 注解的异步调用是没问题的
前提
使用spring-cloud-starter-sleuth jar包版本2.2.8.RELEASE
关于追踪号的xml 配置为
<pattern>%yellow(%date{yyyy-MM-dd HH:mm:ss.SSS}) [%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-B3-ParentSpanId:-},%X{X-Span-Export:-}] %highlight(%-5level) %yellow(%thread) %green(%logger:%line) %msg%n</pattern>
当CompletableFuture有一个任务时,代码的写法
import brave.Span;
import brave.Tracer;
@Autowired
private Tracer tracer;
public String completableFutureTestOne() {
log.info("--------");
Span span = tracer.nextSpan();
CompletableFuture.supplyAsync(()->{
try (Tracer.SpanInScope cleared = tracer.withSpanInScope(span)) {
print("zhangsan");
return "zhangsan";
}catch (Exception e) {
e.printStackTrace();
return "zhangsan";
}
});
return "ok111";
}
当CompletableFuture有多个任务时,代码的写法
import brave.Span;
import brave.Tracer;
import brave.propagation.TraceContext;
@Autowired
private Tracer tracer;
public String completableFutureTest() {
log.info("--------");
TraceContext context = tracer.currentSpan().context();
// 也可以按照下一行获取TraceContext
// TraceContext context = tracer.nextSpan().context();
CompletableFuture.supplyAsync(()->{
Span span = tracer.newChild(context);
try (Tracer.SpanInScope cleared = tracer.withSpanInScope(span)) {
print("zhangsan");
return "zhangsan";
}catch (Exception e) {
e.printStackTrace();
return "zhangsan";
}
});
CompletableFuture.supplyAsync(()->{
Span span = tracer.newChild(context);
try (Tracer.SpanInScope cleared = tracer.withSpanInScope(span)) {
print("lisi");
return "lisi";
}catch (Exception e) {
e.printStackTrace();
return "lisi";
}
});
return "ok";
}
纸上得来终觉浅,绝知此事要躬行。