Приложение Spring Boot 3 Webflux с трассировкой Micrometer, не отображающее traceId и spanId в журналах консоли

Я заменяю Spring Cloud Sleuth для создания корреляции журналов с новым Micrometer Tracing для Spring Boot 3.

Я следил за этим сообщением в блоге , чтобы настроить пример проекта.

Кажется, что traceId/spanId не генерируется автоматически для каждого запроса:

          @GetMapping("/hello")
    fun hello(): String {
        val currentSpan: Span? = tracer.currentSpan()
        logger.info("Hello!")
        return "hello"
    }

currentSpanимеет значение null, и в журнале отображаются пустые строки:

      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. Там и открытый вопрос об этом .

2 ответа

Есть несколько способов добиться этого , в следующем отрывке показаны два из них,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.

Справочная информация по микрометру

Другие вопросы по тегам