13

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

Anoop
  • 813
  • 2
  • 10
  • 24
  • For anyone using Sleuth 3.0, this example seems helpful: https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/#tracingfilter – ch271828n Aug 24 '20 at 14:16

7 Answers7

12

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()
5

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.

Marcin Grzejszczak
  • 10,624
  • 1
  • 16
  • 32
  • Thanks @marcin-grzejszczak. I followed the second approach. – Anoop Jul 19 '17 at 13:18
  • Hi! Any working solution on this? Could you provide some code snippets on how to do it? – Sergei Sirik Jan 04 '18 at 22:58
  • @SergeiSirik https://blog.michaelstrasser.com/2017/07/using-sleuth-trace-id/ (tracer.getCurrentSpan().traceIdString() should do the trick for you to use the trace Id where you need). – Arun Feb 01 '18 at 00:20
  • 1
    In Sleuth 2.0 the method signature to get traceId has changed to: tracer.currentSpan().context().traceId(); – Master Drools Nov 29 '18 at 09:59
  • @MasterDrools for me Trace id is 4ed6e46b52f869f7 but tracer.currentSpan().context().traceId() is returning 5680979129579104759 Any clue on this? – Dhrumil Shah Jan 29 '19 at 05:21
  • @MasterDrools i refer the documentation and found below approach to get current trace id as string using tracer.currentSpan().context().traceIdString(); Hope this will helpful to someone – Dhrumil Shah Jan 29 '19 at 05:29
  • 1
    4ed6e46b52f869f7 is the hexadecimal representation of decimal number 5680979129579104759. – Master Drools Jan 30 '19 at 12:08
5

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

ses
  • 13,174
  • 31
  • 123
  • 226
5

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);
    }

}
ch271828n
  • 15,854
  • 5
  • 53
  • 88
  • This does not work anymore. class TraceWebServletAutoConfiguration is not present in Spring Boot 2.5.0 Does anyone knows the best approach now? – Munish Chandel Jun 03 '21 at 13:44
  • 1
    @MunishChandel what about looking at the value of TRACING_FILTER_ORDER and put it there manually – ch271828n Jun 04 '21 at 12:57
  • @MunishChandel [latest docs](https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/howto.html#how-to-add-headers-to-the-http-server-response) moved this to the how-to section – Stefan Kreidel Mar 06 '23 at 08:16
2

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.

1

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.

1

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.

aksappy
  • 3,400
  • 3
  • 23
  • 49
Robert Ravikumar
  • 912
  • 2
  • 11
  • 29