将来自 Spring Cloud Sleuth 的 traceId 添加到响应中

Adding the traceId from Spring Cloud Sleuth to response

我目前正在我们的项目中实施 Spring Cloud Sleuth。我需要将 traceId 添加到响应 headers。有什么办法可以实现吗?

谢谢,
阿诺普

有2个选项。一种是提供您的自定义提取器 - http://cloud.spring.io/spring-cloud-sleuth/1.0.x/#_customizations(使用 1.2.0 版会更容易)。另一种选择(更快)是创建您自己的过滤器,该过滤器将在执行 TraceFilter 之后和关闭之前注册。您可以在那里 运行 tracer.getCurrentSpan() 并在回复中添加您需要的任何信息。

如果您使用球衣 一种方法是添加球衣响应过滤器 并使用来自 spring sleuth 的 Trace(自动连接) org.springframework.cloud.sleuth.Tracer



public class TraceHeaderInterceptor implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        val responseHeaders = responseContext.getHeaders();
        if (!responseHeaders.containsKey(TRACE_ID_HEADER_NAME)) {
            val traceId = tracer.getCurrentSpan().context().traceIdString();
            responseHeaders.add(TRACE_ID_HEADER_NAME, traceId);
        }
    }

    private static final String TRACE_ID_HEADER_NAME = "X-B3-Traceid";
    private final Tracer tracer;

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

我们将此添加到我们的 API 网关,以避免必须更改每个微服务

您可以通过以下步骤获取。

  1. 自动装配 SpanAccessor。
 @Autowired
private SpanAccessor spanAccessor;
  1. 并在需要的地方添加这一行。
spanAccessor.getCurrentSpan().traceIdString() method to get the value.

希望对您有所帮助。

使用 raj-kumar-bhakthavachalam 示例但使用 springframework.cloud.sleuth 版本 2.1.1 您可以按照以下步骤使用:

1. 自动装配 brave.Tracer

@Autowired
Tracer tracer

2. CurrentSpan returns TraceContext,获取traceIdString

tracer.currentSpan().context().traceIdString()

使用spring 5 和 sleuth 2 时,请使用以下示例。

https://github.com/robert07ravikumar/sleuth-sample

步骤:-

  1. 使用以下代码创建一个 webfilter 并添加来自跟踪器对象的跟踪器 ID。

            @Autowired
            Tracer tracer;
    
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, 
              FilterChain chain) throws IOException, ServletException {
                HttpServletResponse httpServletResponse = (HttpServletResponse) response;
                httpServletResponse.setHeader("tracer-id", tracer.currentSpan().context().traceIdString());
                chain.doFilter(request, response);
            }
    
    
  2. 将注解@ServletComponentScan添加到spring boot main class.

在 Spring Sleuth 3.0.x 中,这是来自 the official doc.

的示例
@Component
@Order(TraceWebServletAutoConfiguration.TRACING_FILTER_ORDER + 1)
class MyFilter extends GenericFilterBean {

    private final Tracer tracer;

    MyFilter(Tracer tracer) {
        this.tracer = tracer;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        Span currentSpan = this.tracer.currentSpan();
        if (currentSpan == null) {
            chain.doFilter(request, response);
            return;
        }
        // for readability we're returning trace id in a hex form
        ((HttpServletResponse) response).addHeader("ZIPKIN-TRACE-ID",
                currentSpan.context().traceIdString());
        // we can also add some custom tags
        currentSpan.tag("custom", "tag");
        chain.doFilter(request, response);
    }

}

从 sleuth 检索 traceId 的最简单方法是使用 MDC。 使用此方法:MDC.get("traceId") 将 return 具有该值的字符串,并且可以用它做任何你想做的事。

关于把那个信息放在header里,上面的回答已经很清楚地说明了怎么做。