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
相关产品推荐
相关产品推荐

