骆熙华 发表于 2025-10-20 16:25:00

SpringBoot使用TraceId日志链路追踪


[*]业务需求
  保证一次服务调用,在业务中可以一次追查到本次服务调用涉及的本地服务方法,第三方服务接口。实现日志的链路追踪。保证日志的高查找性。

[*]实现步骤
  1、pom.xml 依赖

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      spring-boot-starter-logging</artifactId>
    </dependency>
   
    <dependency>
      <groupId>org.projectlombok</groupId>
      lombok</artifactId>
      <version>1.16.10</version>
    </dependency>
</dependencies>2、整合logback,打印日志,logback.xml (日志配置文件)

关键代码:,traceId是通过拦截器里MDC.put(traceId, tid)添加。
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
   
    <property name="log" value="D:/test/log" />
   
   
      <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
      </encoder>
    </appender>
   
   
      <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>%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">
      
      
    </root>
</configuration>3、application.yml指定logback.xml配置目录

logging:
config: classpath:logback.xml4、异步线程的跟踪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();
            }
      };
    }注:萌新一枚,该博客用于记录所学知识,如有不对的地方,请及时指教,谢谢各位。
2025-10-20 15:46:36

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

鞍汉 发表于 2025-10-28 04:37:18

谢谢分享,试用一下

庾芷秋 发表于 前天 23:30

用心讨论,共获提升!
页: [1]
查看完整版本: SpringBoot使用TraceId日志链路追踪