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

Spring Boot 3中ErrorPage跳转时Tracer.currentSpan()为空致TraceId获取失败

问题解决:Spring Boot 3中ErrorPage无法获取Micrometer Trace上下文

核心原因

Spring Boot 3用Micrometer Tracing替代了Spring Cloud Sleuth,两者的Trace上下文传播机制存在差异。Spring Boot 2.7的Sleuth会自动为ErrorPage的重定向链路携带Trace上下文,但Micrometer Tracing默认未配置该场景的上下文传递逻辑,导致ErrorPage请求中无法获取到当前Span。

解决方案

1. 自定义Trace上下文传播过滤器

创建过滤器,在ErrorPage请求到达时,从原始异常请求的属性中恢复Trace上下文:

import io.micrometer.tracing.Tracer;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import java.io.IOException;

@Component
public class ErrorPageTracePropagationFilter implements Filter {

    private final Tracer tracer;

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

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        // 从Spring Boot存储的原始异常请求中获取上下文
        HttpServletRequest originalRequest = (HttpServletRequest) httpRequest.getAttribute("javax.servlet.error.request");
        
        if (originalRequest != null) {
            // 基于原始请求的Trace信息创建新Span并绑定上下文
            var span = tracer.nextSpan().name("error-page-processing").start();
            try (var scope = tracer.withSpan(span)) {
                chain.doFilter(request, response);
            } finally {
                span.end();
            }
        } else {
            chain.doFilter(request, response);
        }
    }
}

2. 配置Micrometer Tracing传播规则

在application.yml中添加配置,保持和原Sleuth兼容的B3传播格式:

micrometer:
  tracing:
    propagation:
      type: B3
    baggage:
      enabled: true
      remote-fields: traceId, spanId

3. 确保ErrorPage注册逻辑正确

如果通过代码注册ErrorPage,需保证注册逻辑生效:

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
public class CustomErrorPageRegistrar implements ErrorPageRegistrar {
    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error"));
    }
}

验证方法

触发一个会跳转到ErrorPage的异常,在ErrorPage的处理逻辑中调用tracer.currentSpan().context().traceId(),确认TraceId已正常获取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:44:51