我将使用 Spring Boot 3 的新 Micrometer Tracing 替换 Spring Cloud Sleuth 以生成日志相关性。
traceId/spanId 似乎不会根据请求自动生成:
@GetMapping("/hello")
fun hello(): String {
val currentSpan: Span? = tracer.currentSpan()
logger.info("Hello!")
return "hello"
}
currentSpan
为空,日志显示空字符串:
2022-11-28T14:53:05.335+01:00 INFO [server,,] 9176 --- [ctor-http-nio-2] d.DemotracingApplication$$SpringCGLIB$$0 : Hello!
这是我当前的配置:
logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
以及依赖项:
dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-aop")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.micrometer:micrometer-tracing-bridge-brave")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("io.micrometer:micrometer-registry-prometheus")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
}
为什么不起作用?
编辑:
WebMVC 应用程序不受此问题影响,并在升级后记录相关信息。
Webflux 应用程序的行为似乎发生了变化。有一个关于此的未决问题。
有多种方法来实现它,以下摘录显示了其中两种,
ContextSnapshot.setThreadLocalsFrom
和handle()
运算符
@GetMapping("/hello")
fun hello(): Mono<String> {
return Mono.deferContextual { contextView: ContextView ->
ContextSnapshot.setThreadLocalsFrom(contextView, ObservationThreadLocalAccessor.KEY)
.use { scope: ContextSnapshot.Scope ->
val traceId = tracer.currentSpan()!!.context().traceId()
logger.info("<ACCEPTANCE_TEST> <TRACE:{}> Hello!", traceId)
webClient.get().uri("http://localhost:7654/helloWc")
.retrieve()
.bodyToMono(String::class.java)
.handle { t: String, u: SynchronousSink<String> ->
logger.info("Retrieved helloWc {}", t)
u.next(t)
}
}
}
}
目前有一个更简单的解决方案,将
Hooks.enableAutomaticContextPropagation();
放入您的主要方法中。
public static void main(final String[] args) {
Hooks.enableAutomaticContextPropagation();
SpringApplication.run(Application.class, args);
}
有了这个,我们就不需要做任何其他事情来透明地传播和记录 Webflux 应用程序中的跟踪信息。
请随意检查我的演示项目spring-cloud-gateway-upgrade,其中包含分支“spring-boot-3.x-upgrade”(基于我的问题)。它显示了为所有想要的记录器(例如访问日志)进行跟踪所需的额外设置