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
You can set a trace ID when you're doing the HTTP call with the X-Cloud-Trace-Context header, while the request id is the way GCP has to uniquely identify each request. All requests have an ID, while only some have traces. Only the traced requests will send their info to the Stackdriver Trace API.
TraceId – This is an id that is assigned to a single request, job, or action. Something like each unique user initiated web request will have its own traceId. SpanId – Tracks a unit of work. Think of a request that consists of multiple steps.
When a request enters an instrumented application, the agent creates a unique trace context (aka Trace ID) and maintains it through the lifetime of the transaction in order to report performance metrics, and if sampled, the transaction trace.
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);
}
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With