You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Sleuth日志中添加X-B3-TraceId请求头信息

解决Spring Boot Sleuth日志中添加X-B3-TraceId请求头的问题

方案1:基于MDC自定义日志格式(推荐)

通过MDC(映射诊断上下文)存储请求头信息,再修改日志格式将其输出,是最直接的实现方式。

步骤1:编写请求头拦截器

创建拦截器提取X-B3-TraceId并放入MDC,请求结束后清理:

import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class RequestTraceIdInterceptor implements HandlerInterceptor {
    private static final String REQUEST_TRACE_ID_KEY = "requestTraceId";
    private static final String X_B3_TRACE_ID_HEADER = "X-B3-TraceId";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String traceIdHeader = request.getHeader(X_B3_TRACE_ID_HEADER);
        if (traceIdHeader != null) {
            MDC.put(REQUEST_TRACE_ID_KEY, traceIdHeader);
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        MDC.remove(REQUEST_TRACE_ID_KEY);
    }
}

步骤2:注册拦截器

将拦截器加入Spring MVC的拦截器链,覆盖所有API路径:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    private final RequestTraceIdInterceptor traceIdInterceptor;

    public WebMvcConfig(RequestTraceIdInterceptor traceIdInterceptor) {
        this.traceIdInterceptor = traceIdInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(traceIdInterceptor).addPathPatterns("/**");
    }
}

步骤3:修改日志格式配置

在application.properties或application.yml中更新日志格式,引入MDC中的requestTraceId:

# application.properties
logging.pattern.level=%5p [%X{spring.application.name},%X{traceId},%X{spanId},%X{requestTraceId:-null}]

YAML格式:

# application.yml
logging:
  pattern:
    level: "%5p [%X{spring.application.name},%X{traceId},%X{spanId},%X{requestTraceId:-null}]"

最终日志输出示例:

2022-11-02 17:45:16.176 INFO [app-name,c9f95e8f223dca74,c9f95e8f223dca74,abc123456789] 35436 - ...

方案2:自定义Sleuth Span日志逻辑

如果需要和Sleuth Span深度绑定,可以自定义SpanLogger实现:

步骤1:给Span添加请求头标签

在拦截器中把X-B3-TraceId作为Span的标签存储:

// 在RequestTraceIdInterceptor的preHandle方法中添加
import org.springframework.cloud.sleuth.Tracer;
// 注入Tracer
private final Tracer tracer;

// ...
if (traceIdHeader != null) {
    tracer.currentSpan().tag(X_B3_TRACE_ID_HEADER, traceIdHeader);
}

步骤2:自定义SpanLogger

实现Sleuth的SpanLogger接口,在日志中输出请求头信息:

import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.log.SpanLogger;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
public class CustomSpanLogger implements SpanLogger {
    private static final Logger log = LoggerFactory.getLogger(CustomSpanLogger.class);
    private static final String X_B3_TRACE_ID_HEADER = "X-B3-TraceId";

    @Override
    public void logStartedSpan(Span span) {
        String requestTraceId = span.tag(X_B3_TRACE_ID_HEADER);
        log.info("Span started | app: {}, traceId: {}, spanId: {}, requestTraceId: {}",
                span.serviceName(), span.traceId(), span.spanId(), requestTraceId);
    }

    // 按需实现logStoppedSpan、logAbortedSpan等方法
}

注意事项

  • 若请求中无X-B3-TraceId头,可通过%X{requestTraceId:-null}设置默认值避免空值
  • Sleuth 3.1.x已与Micrometer Tracing整合,代码需适配对应版本的API
  • 拦截器需覆盖所有需要追踪的API路径,确保请求头能被正确提取

内容的提问来源于stack exchange,提问作者Viraj Dhamal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:05:23