当前位置: 首页 > 知识库问答 >
问题:

即使在TraceWebFilter之后注册,TraceId和SpanId在WebFilter中也为null

宋景福
2023-03-14

我目前在Spring Boot中使用2020.0.0,注册了一个自定义web过滤器,该过滤器记录请求中的信息(顺序是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为空
  • 日志tracer.currentSpan in log is null

有什么线索说明为什么会这样吗?

共有1个答案

段渊
2023-03-14

如果您查看TraceWebFilter,您将看到它没有将任何内容放入MDC(MDC基本上是一个线程局部,您处于一个异步事件循环)。

>

  • 但它与跟踪器进行交互,您也可以将跟踪器注入到过滤器中,并从中获取当前跨度:跟踪器。currentSpan(),从Span的TraceContext可以得到traceId和spanId。

    此外,它将Span放入Exchange属性中:

    this.exchange.getAttributes().put(TRACE_REQUEST_ATTR, span);
    

    我建议将跟踪程序注入过滤器中,并从中获取当前Span。

  •  类似资料:
    • TraceId 生成规则 SOFATracer 通过 TraceId 来将一个请求在各个服务器上的调用日志串联起来,TraceId 一般由接收请求经过的第一个服务器产生,产生规则是: 服务器 IP + 产生 ID 时候的时间 + 自增序列 + 当前进程号 ,比如: 0ad1348f1403169275002100356696 前 8 位 0ad1348f 即产生 TraceId 的机器的 IP,

    • 例如,在包括Spring Cloud Sleuth之前,人们会在他们的日志中得到这样的东西 在应用程序名称附近有2个逗号(即traceID和spanID将显示的位置)。但我的日志最初看起来像这样 为了在日志中获取应用程序名称,我在application.properties中编写了以下代码 现在,我的日志看起来是这样的(如果您观察到,它在应用程序名称旁边没有2个逗号) 即使包括了Sleuth,我的

    • SLF4J 提供了 MDC (Mapped Diagnostic Contexts)功能,可以支持用户定义和修改日志的输出格式以及内容。本文将介绍 SOFATracer 集成的 SLF4J MDC功能,方便用户在只简单修改日志配置文件的前提下输出当前 SOFATracer 上下文 TraceId 以及 SpanId 。 使用前提 为了在应用中的日志正确打印 TraceId 和 SpanId 参数,

    • spring的侦探增加了MDC的X-B3-SpanId和SpanID。(TraceId相同) “x-b3-”前缀值与非前缀值相同。 如果其中一个值是多余的,我倾向于删除它。(减少日志的冗长) X-B3-SpanId和SPANID有什么区别吗?(X-B3-TraceId和Traceid) 是否有充分的理由将两者都记录下来? spring文档https://cloud.spring.io/spring

    • 根据Spring Doc API http://docs.Spring.io/Spring-framework/docs/current/javadoc-api/index.html?org/springframework/web/context/contextloaderlistener.html- 这个(ContextLoaderListener)监听器应该注册在web.xml中的Log4jC

    • 我正在尝试通过使用spring-cloud d-gcp-starter-log将SpringBootApplication(微服务)与StackdriverLogging集成。我能够在GCP中看到日志,但在日志中traceId和SPANId丢失。为此,我也尝试使用Spring-cloud d-sleuth,但由于我在我的微服务中使用apache kafka,因此侦探无法正常工作。有人能帮我吗我如何