Adding the traceId from Spring Cloud Sleuth to response

25.2k views Asked by At

I am currently implementing Spring Cloud Sleuth in our project. I have a requirement to add the traceId to the response headers. Is there a way that this can be achieved?

Thanks,
Anoop

7

There are 7 answers

7
Marcin Grzejszczak On BEST ANSWER

There are 2 options. One is to provide your custom extractors - http://cloud.spring.io/spring-cloud-sleuth/1.0.x/#_customizations (it will be MUCH easier with version 1.2.0). Another option (much faster) is to create your own Filter that will be registered after TraceFilter was executed and before it's closed. You can there run tracer.getCurrentSpan() and add any info you need to the response.

1
Gustavo Roversi On

The easiest way to retrieve traceId from sleuth is using MDC. Using this method: MDC.get("traceId") will return a string with the value, and can do whatever you want with it.

About putting that information in header, the answers above have clearly showed how to do.

0
Robert Ravikumar On

When using spring 5 and sleuth 2 , Please use the below sample.

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

Steps : -

  1. Create a webfilter with the below code and add the tracer id from the tracer object.

            @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. Add the annotation @ServletComponentScan to the spring boot main class.

0
Níkolas La Porta On

Using raj-kumar-bhakthavachalam example but using springframework.cloud.sleuth version 2.1.1 you may use as the following steps:

1. Autowired brave.Tracer

@Autowired
Tracer tracer

2. CurrentSpan returns TraceContext, get traceIdString

tracer.currentSpan().context().traceIdString()
0
Vikrant Kandgaonkar On

If you're using jersey One approach is to add jersey response filter and use Trace (autowired) from spring sleuth 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;
    }
}

We added this to our API gateway to avoid having to change each and every microservice

0
Raj kumar Bhakthavachalam On

You can get it by below steps.

  1. Autowire SpanAccessor.
 @Autowired
private SpanAccessor spanAccessor;
  1. And add this line wherever required.
spanAccessor.getCurrentSpan().traceIdString() method to get the value.

Hope it helps.

3
ch271828n On

In Spring Sleuth 3.0.x, here is an example from 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);
    }

}