traceId и SpanId равны нулю в WebFilter, даже если он зарегистрирован после TraceWebFilter

#java #spring-boot #spring-webflux #spring-cloud-sleuth #opentracing

#java #весенняя загрузка #spring-webflux #spring-cloud-sleuth #opentracing

Вопрос:

В настоящее время я использую 2020.0.0 Spring Boot 2.4.2 и зарегистрировал пользовательский веб-фильтр, который регистрирует информацию из запроса (порядок webProperties.filterOrder 1 — поэтому он должен быть зарегистрирован после TraceWebFilter). По какой-то причине traceId и spanId отсутствуют в MDC (и, следовательно, не регистрируются).

Реализация WebFilter:

 class TraceWebFilter(
        private val webProperties: SleuthWebProperties,
        private val tracer: Tracer
): WebFilter, Ordered {
    override fun getOrder(): Int = webProperties.filterOrder   1

    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        logger.debug { "Building trace web filter" }

        return Mono.defer {
            MDC.put("Request-Method", exchange.request.method?.toString())
            MDC.put("Request-Path", exchange.request.path.toString())

            logger.info { tracer.currentSpan() }

            logger.info { ">> headers=${exchange.request.headers}" }
            logger.info { ">> method=${exchange.request.method}" }
            logger.info { ">> path=${exchange.request.path}" }

            exchange.response.beforeCommit {
                Mono.fromRunnable {
                    logger.info { "<< headers=${exchange.response.headers}" }
                    logger.info { "<< status=${exchange.response.rawStatusCode}" }
                }
            }

            chain.filter(exchange)
        }
    }
}
 

Журналы:

 app_1       | 2021-01-28 04:43:24.420 DEBUG [user-service,method=,path=,traceId=,spanId=] 1 --- [p-nio-80-exec-2] o.s.c.s.instrument.web.TraceWebFilter    : Received a request to uri [/users]
app_1       | 2021-01-28 04:43:24.566 DEBUG [user-service,method=,path=,traceId=,spanId=] 1 --- [p-nio-80-exec-2] o.s.c.s.instrument.web.TraceWebFilter    : Handled receive of span RealSpan(9b7383611e5a3bc2/9b7383611e5a3bc2)
app_1       | 2021-01-28 04:43:24.633 DEBUG [user-service,method=,path=,traceId=,spanId=] 1 --- [p-nio-80-exec-2] c.p.p.components.tracing.TraceWebFilter  : Building trace web filter
app_1       | 2021-01-28 04:43:24.638  INFO [user-service,method=POST,path=/users,traceId=,spanId=] 1 --- [p-nio-80-exec-2] c.p.p.components.tracing.TraceWebFilter  : null
app_1       | 2021-01-28 04:43:24.694  INFO [user-service,method=POST,path=/users,traceId=,spanId=] 1 --- [p-nio-80-exec-2] c.p.p.components.tracing.TraceWebFilter  : >> headers=[content-type:"application/json", user-agent:"PostmanRuntime/7.26.8", accept:"*/*", cache-control:"no-cache", postman-token:"18d99e30-ce7a-4659-a2c1-21020d8bf2b5", host:"localhost:9100", accept-encoding:"gzip, deflate, br", connection:"keep-alive", content-length:"2"]
app_1       | 2021-01-28 04:43:24.699  INFO [user-service,method=POST,path=/users,traceId=,spanId=] 1 --- [p-nio-80-exec-2] c.p.p.components.tracing.TraceWebFilter  : >> method=POST
app_1       | 2021-01-28 04:43:24.747  INFO [user-service,method=POST,path=/users,traceId=,spanId=] 1 --- [p-nio-80-exec-2] c.p.p.components.tracing.TraceWebFilter  : >> path=/users
 

Пожалуйста, обратите внимание на следующее:

  • traceId и spanId в журналах равны нулю
  • logged tracer.currentSpan в журналах имеет значение null

Есть какие-либо подсказки относительно того, почему это происходит?

Комментарии:

1. К сожалению, вы не можете использовать MDC в Reactor world

2. MDC можно использовать в мире реакторов. Просто вызовите Kotlin с помощью loggingcontext, чтобы настроить его

Ответ №1:

Если вы посмотрите TraceWebFilter , вы увидите, что он ничего не помещает в MDC ( MDC по сути, это a ThreadLocal , и вы находитесь в цикле асинхронных событий).

  1. Но он взаимодействует с Tracer тем, что вы также можете ввести в свой фильтр и получить из него текущий диапазон: tracer.currentSpan() и из TraceContext из Span вы можете получить traceId и spanId .
  2. Кроме того, он помещает Span в атрибуты Exchange:
 this.exchange.getAttributes().put(TRACE_REQUEST_ATTR, span);
 

Я рекомендую ввести Tracer в ваш фильтр и получить Span из него ток.

Комментарии:

1. Я замечаю, что к моменту выполнения контроллера traceId и spanId уже находятся в MDC. Есть ли конкретный компонент, который это делает? Есть ли способ добавить мой пользовательский веб-фильтр после этого?

2. Я также попытался ввести Tracer и получить доступ tracer.currentSpan() , и он вернул null. Обновил вопрос, чтобы отразить это.