Angelo Immediata
Angelo Immediata

Reputation: 6944

Spring cloud sleuth - tracing from FE to BE

I'm using springboot 2.7.5 and spring cloud sleuth 3.1.5

I have a distributed system composed by more than 30 microservices. I have an Angular front-end deployed in a ngninx container and from this FE I call all my MS. I don't use an API GW

What I'd love to obtain by using sleuth is to be able in correlating all the MS an user used. As far as I know, sleuth is able in propagating the traceID and spanID between MS.

How can I configure sleuth in order to tell him: if in the request is present the header "my-correlation-id", this is your traceID and you must not generate it, you must add a span to it; if it's not present, generate a new trace id and send it back to the FE in a response header.

Is there any configuration I can use?

Note that it's not mandatory to me to use the header "my-correlation-id"; if sleuth already provides its own header I can use the provided header

Thank you

Angelo

Upvotes: 2

Views: 704

Answers (1)

Marcin Grzejszczak
Marcin Grzejszczak

Reputation: 11169

You can create and register a simple HTTP filter that will retrieve the current span and add the trace id to the response headers. Check this section of the docs for reference https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/howto.html#how-to-add-headers-to-the-http-server-response

I'm copying the code for your convenience

import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;

import javax.servlet.Filter;
import org.springframework.web.server.WebFilter;

@Configuration(proxyBeanMethods = false)
class MyConfig {

        // Example of a servlet Filter for non-reactive applications
        @Bean
        Filter traceIdInResponseFilter(Tracer tracer) {
            return (request, response, chain) -> {
                Span currentSpan = tracer.currentSpan();
                if (currentSpan != null) {
                    HttpServletResponse resp = (HttpServletResponse) response;
                    // putting trace id value in [mytraceid] response header
                    resp.addHeader("mytraceid", currentSpan.context().traceId());
                }
                chain.doFilter(request, response);
            };
        }

        // Example of a reactive WebFilter for reactive applications
        @Bean
        WebFilter traceIdInResponseFilter(Tracer tracer) {
            return (exchange, chain) -> {
                Span currentSpan = tracer.currentSpan();
                if (currentSpan != null) {
                    // putting trace id value in [mytraceid] response header
                    exchange.getResponse().getHeaders().add("mytraceid", currentSpan.context().traceId());
                }
                return chain.filter(exchange);
            };
        }
}

Upvotes: 1

Related Questions