Spring Boot 3+Micrometer下如何为CommandLineRunner开启Trace-ID上下文传播?
Spring Boot 3 + Micrometer 下为 CommandLineRunner 开启 Trace-ID 上下文传播的方案
方法1:使用 @Observed 注解自动管理追踪上下文
Micrometer Tracing 在 Spring Boot 3 中基于 Observation API 实现追踪,CommandLineRunner 不像 Web 请求那样有自动的上下文初始化,需要通过 @Observed 注解显式触发追踪上下文的创建:
修改你的 JobRunner 类:
import io.micrometer.observation.annotation.Observed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class JobRunner implements CommandLineRunner { private static final Logger log = LoggerFactory.getLogger(JobRunner.class); private final PetsJobExecutor petsJobExecutor; public JobRunner(PetsJobExecutor petsJobExecutor) { this.petsJobExecutor = petsJobExecutor; } @Observed(name = "job.run", contextualName = "pets-update-job") @TrackExecutionTime @Override public void run(String... args) { log.info("Started the job"); petsJobExecutor.updatePets(); log.info("Finished the job"); } }
@Observed会自动为方法创建一个追踪 Span,初始化 Trace-ID 上下文,日志中的%X{traceId}就能正常输出。name和contextualName用于标识这个追踪任务,方便在监控系统中区分。
方法2:手动初始化追踪上下文(适合更灵活的场景)
如果需要更精细的控制,可以通过 ObservationRegistry 手动启动一个 Observation 来包裹业务逻辑:
import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class JobRunner implements CommandLineRunner { private static final Logger log = LoggerFactory.getLogger(JobRunner.class); private final PetsJobExecutor petsJobExecutor; private final ObservationRegistry observationRegistry; public JobRunner(PetsJobExecutor petsJobExecutor, ObservationRegistry observationRegistry) { this.petsJobExecutor = petsJobExecutor; this.observationRegistry = observationRegistry; } @TrackExecutionTime @Override public void run(String... args) { Observation.createNotStarted("job.run", observationRegistry) .contextualName("pets-update-job") .observe(() -> { log.info("Started the job"); petsJobExecutor.updatePets(); log.info("Finished the job"); }); } }
这种方式手动控制追踪上下文的生命周期,适合需要在代码中自定义 Span 内容的场景。
必要的依赖检查
确保你的项目中已经引入了 Micrometer Tracing 的相关依赖(以 Brave 为例):
<!-- pom.xml --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-tracing-bridge-brave</artifactId> </dependency>
如果使用 Gradle,对应依赖如下:
// build.gradle implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-tracing-bridge-brave'
日志配置确认
虽然你的 Rest 控制器已经能输出 Trace-ID,还是确认下日志格式配置(以 logback 为例),确保包含 Trace-ID 和 Span-ID:
<!-- logback-spring.xml --> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} %X{traceId:-} %X{spanId:-} - %msg%n</pattern>
内容的提问来源于stack exchange,提问作者MariaLO
相关产品推荐
相关产品推荐

