Skywalking 官方不支持 Log4j 的异步线程打印 traceId,官方给出的答复是:用户通过线程间 traceid 传递解决。
Issue 地址:apache/skywalking#2938
同时官方也给出了跨线程追踪的解决方案,详见:跨线程追踪。具体有以下几种方法。
@TraceCrossThread
public static class MyCallable<String> implements Callable<String> {
@Override
public String call() throws Exception {
return null;
}
}
...
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(new MyCallable());
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(CallableWrapper.of(new Callable<String>() {
@Override
public String call() throws Exception {
return null;
}
}));
或者
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.execute(RunnableWrapper.of(new Runnable() {
@Override
public void run() {
//your code
}
}));
@TraceCrossThread
public class MySupplier<String> implements Supplier<String> {
@Override
public String get() {
return null;
}
}
CompletableFuture.supplyAsync(new MySupplier<String>());
或者
CompletableFuture.supplyAsync(SupplierWrapper.of(() -> {
return "SupplierWrapper";
})).thenAccept(System.out::println);
社区对 Spring 的 @Async 注解进行了增强,支持子线程的 traceId 打印。代码实现详见:apache/skywalking#2902
在应用启动类上添加 @EnableAsync 注解:
@EnableAsync
@SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
接口定义如下:
@Slf4j
@RestController
public class ExampleController {
@Autowired
private ExampleService exampleService;
@GetMapping("/traceid")
public void traceid() {
log.info("main thread");
exampleService.asyncMethod();
}
}
使用 @Async 注解:
@Slf4j
@Service
public class ExampleService {
@Async
public void asyncMethod() {
log.info("async method call.");
}
}
日志打印如下: