Adding the traceId from Spring Cloud Sleuth to response
Asked Answered
G

7

15

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

Griffon answered 19/12, 2016 at 12:16 Comment(1)
For anyone using Sleuth 3.0, this example seems helpful: docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/…Vasti
G
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.

Gilcrest answered 19/12, 2016 at 12:22 Comment(7)
Thanks @marcin-grzejszczak. I followed the second approach.Griffon
Hi! Any working solution on this? Could you provide some code snippets on how to do it?Phono
@SergeiSirik 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).Bruxelles
In Sleuth 2.0 the method signature to get traceId has changed to: tracer.currentSpan().context().traceId();Bodoni
@MasterDrools for me Trace id is 4ed6e46b52f869f7 but tracer.currentSpan().context().traceId() is returning 5680979129579104759 Any clue on this?Ponceau
@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 someonePonceau
4ed6e46b52f869f7 is the hexadecimal representation of decimal number 5680979129579104759.Bodoni
K
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()
Kaolin answered 3/11, 2019 at 22:4 Comment(0)
G
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.

Gilcrest answered 19/12, 2016 at 12:22 Comment(7)
Thanks @marcin-grzejszczak. I followed the second approach.Griffon
Hi! Any working solution on this? Could you provide some code snippets on how to do it?Phono
@SergeiSirik 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).Bruxelles
In Sleuth 2.0 the method signature to get traceId has changed to: tracer.currentSpan().context().traceId();Bodoni
@MasterDrools for me Trace id is 4ed6e46b52f869f7 but tracer.currentSpan().context().traceId() is returning 5680979129579104759 Any clue on this?Ponceau
@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 someonePonceau
4ed6e46b52f869f7 is the hexadecimal representation of decimal number 5680979129579104759.Bodoni
H
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

Has answered 3/12, 2018 at 13:58 Comment(0)
V
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);
    }

}
Vasti answered 24/8, 2020 at 14:21 Comment(3)
This does not work anymore. class TraceWebServletAutoConfiguration is not present in Spring Boot 2.5.0 Does anyone knows the best approach now?Mischief
@MunishChandel what about looking at the value of TRACING_FILTER_ORDER and put it there manuallyVasti
@MunishChandel latest docs moved this to the how-to sectionAvra
F
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.

Falsity answered 10/2, 2021 at 17:28 Comment(1)
this works in Spring Boot 3 alongside with micrometer. Just get directly from MDC. Thanks.Monocyte
L
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.

Limerick answered 2/7, 2019 at 6:55 Comment(0)
F
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.

Frieder answered 2/12, 2019 at 16:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.