#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
, и вы находитесь в цикле асинхронных событий).
- Но он взаимодействует с
Tracer
тем, что вы также можете ввести в свой фильтр и получить из него текущий диапазон:tracer.currentSpan()
и изTraceContext
изSpan
вы можете получитьtraceId
иspanId
. - Кроме того, он помещает
Span
в атрибуты Exchange:
this.exchange.getAttributes().put(TRACE_REQUEST_ATTR, span);
Я рекомендую ввести Tracer
в ваш фильтр и получить Span
из него ток.
Комментарии:
1. Я замечаю, что к моменту выполнения контроллера traceId и spanId уже находятся в MDC. Есть ли конкретный компонент, который это делает? Есть ли способ добавить мой пользовательский веб-фильтр после этого?
2. Я также попытался ввести
Tracer
и получить доступtracer.currentSpan()
, и он вернул null. Обновил вопрос, чтобы отразить это.