SpringBoot使用TraceId实现日志链路追踪的步骤
作者:码农小周
本文介绍了如何实现服务调用的日志链路追踪,包括整合logback打印traceId、配置日志文件、通过MDC传递追踪ID,并重写线程池方法以保证异步和定时任务线程的traceId传递,实现高效日志查找和追踪,感兴趣的朋友跟随小编一起看看吧
- 业务需求
保证一次服务调用,在业务中可以一次追查到本次服务调用涉及的本地服务方法,第三方服务接口。实现日志的链路追踪。保证日志的高查找性。
- 实现步骤
1、pom.xml 依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!--lombok配置-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>2、整合logback,打印日志,logback.xml (日志配置文件)
关键代码:[traceId:%X{traceId}],traceId是通过拦截器里MDC.put(traceId, tid)添加。
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--日志存储路径-->
<property name="log" value="D:/test/log" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--输出格式化-->
<pattern>[traceId:%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按天生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件名-->
<FileNamePattern>${log}/%d{yyyy-MM-dd}.log</FileNamePattern>
<!--保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>[traceId:%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
</configuration>3、application.yml指定logback.xml配置目录
logging: config: classpath:logback.xml
4、异步线程的跟踪ID链路追踪
业务逻辑是基于线程数据的传递进行处理,主线程传递线程ID到子线程。处理方式:重写线程池的execute(*)、submit(*)方法。
public final class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
public MyThreadPoolTaskExecutor() {
super();
}
@Override
public void execute(Runnable task) {
super.execute(TraceIdUtil.wrap(task, MDC.getCopyOfContextMap()));
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(TraceIdUtil.wrap(task, MDC.getCopyOfContextMap()));
}
@Override
public Future<?> submit(Runnable task) {
return super.submit(TraceIdUtil.wrap(task, MDC.getCopyOfContextMap()));
}
}4、异步定时任务线程接口ScheduledExecutorService的日志链路追踪。在执行前,执行后进行跟踪ID的生成和删除。
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService() {
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
new ThreadPoolExecutor.CallerRunsPolicy()) {
@Override
protected void beforeExecute(Thread thread, Runnable runnable) {
super.beforeExecute(thread, runnable);
// 为定时任务生成一个 traceId
TraceIdUtil.setTraceId();
// 可选:添加任务标识
System.out.println("Scheduled task starting with traceId: " + TraceIdUtil.getTraceId());
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Threads.printException(r, t);
TraceIdUtil.remove();
}
};
}到此这篇关于SpringBoot使用TraceId日志链路追踪的文章就介绍到这了,更多相关SpringBoot TraceId日志链路追踪内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
