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

Spring Cloud Sleuth 2.x WebFlux项目自定义trace id实现方案咨询

适配Spring Cloud Sleuth 2.2.8 + WebFlux 自定义TraceId实现方案

第一步:基础配置修改

先在application.yml中调整Sleuth默认传播规则,替换链路Header名称为correlation-id:

spring:
  sleuth:
    # 声明自定义传播的Header名称
    propagation-keys:
      - correlation-id
    # 关闭默认B3协议传播规则
    b3:
      enabled: false
    baggage:
      correlation:
        # 保证traceId自动注入MDC上下文
        fields:
          - traceId
        enabled: true
  # 若自定义traceId不符合16/32位十六进制规则,开启以下配置关闭格式校验
  # sleuth:
  #   trace-id128: true
  #   supports-join: false

第二步:自定义TraceId注入Filter(WebFlux适配)

实现优先级低于Sleuth默认链路Filter的WebFilter,在Sleuth初始化链路后替换默认traceId为自定义拼接值:

import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Component
// Sleuth默认TraceWebFilter优先级是HIGHEST_PRECEDENCE + 10,此处优先级更低,保证Sleuth先创建初始Span
@Order(Ordered.HIGHEST_PRECEDENCE + 15)
public class CustomTraceIdFilter implements WebFilter {

    private final Tracer tracer;

    public CustomTraceIdFilter(Tracer tracer) {
        this.tracer = tracer;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String customTraceId;
        // 优先读取请求头中的correlation-id作为traceId
        customTraceId = request.getHeaders().getFirst("correlation-id");
        if (customTraceId == null) {
            // 从请求中获取三个参数拼接,此处示例为从query参数取,实际可根据需求调整为从请求体、路径变量取值
            String param1 = request.getQueryParams().getFirst("param1");
            String param2 = request.getQueryParams().getFirst("param2");
            String param3 = request.getQueryParams().getFirst("param3");
            // 自定义拼接规则,可自行调整
            customTraceId = String.join("_", param1, param2, param3);
        }
        // 替换当前链路的traceId
        Span currentSpan = tracer.currentSpan();
        if (currentSpan != null) {
            Span modifiedSpan = currentSpan.toBuilder()
                    .traceId(customTraceId)
                    .build();
            // 将修改后的Span写入响应式上下文
            return chain.filter(exchange)
                    .contextWrite(tracer.withSpan(modifiedSpan));
        }
        return chain.filter(exchange);
    }
}

注意:如果三个参数存放在POST请求体中,需要先在Filter中缓存请求体数据,避免流只能读取一次导致后续业务逻辑报错。

第三步:WebClient自动携带Header配置

如果使用Spring容器自动注入的WebClient,Sleuth会自动将correlation-id注入到请求头中,无需额外配置。如果是手动构建的WebClient,需要添加Sleuth的链路过滤器:

import org.springframework.cloud.sleuth.instrument.web.client.TraceExchangeFilterFunction;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebClientConfig {
    @Bean
    public WebClient customWebClient(TraceExchangeFilterFunction traceFilter) {
        return WebClient.builder()
                .filter(traceFilter)
                .build();
    }
}

第四步:日志配置

原有log4j.xml中配置的%X{traceId}不需要修改,自定义traceId会自动注入到MDC上下文,直接就能按原有规则打印到所有日志中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:54:03