Issue
Currently, I am integrating Sleuth into our existing Microservices to enhance the logging mechanism. The MS is using Spring Cloud Sleuth 3.0.6
The challenge that I am trying to solve is while making outbound API calls, we are creating RestTemplate using new() keyword instead of managing RestTemplate as Bean. Due to this, the traceids vary in the MS1 and MS2 logs, which makes the tracing difficult.
As I understand from the official doc, Brave registers interceptors to like LazyTraceClientHttpRequestInterceptor & TracingClientHttpRequestInterceptor to add headers like X-B3-Traceid, X-B3-SpanId to the outbound request, I tried to do something similar.
Here is the code for my custom Interceptor:
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
@Component
public class RequestResponseLoggingInterceptor implements ClientHttpRequestInterceptor {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private Tracer tracer;
RequestResponseLoggingInterceptor(Tracer tracer){
this.tracer = tracer;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException
{
Span span = tracer.currentSpan();
HttpHeaders headers = new HttpHeaders();
headers.set("X-B3-Traceid", span.context().traceId());
headers.set("X-B3-SpanId", span.context().spanId());
headers.set("X-B3-ParentSpanId", span.context().parentId());
request.getHeaders().addAll(headers);
ClientHttpResponse response = execution.execute(request, body);
return response;
}
}
And In my controller class, I have autowired this interceptor. And using this interceptor for the resttemplate call.
When I am comparing the MS1 and MS2 logs for this API call, the traceids are different.
Can anyone help me what am I doing wrong here? And how can I achieve this traceid propagation to downstream service By Creating RestTemplate with New() keyword.
Solution
You need to inject TracingClientHttpRequestInterceptor
bean to your rest template and it will take care of passing the tracing context.
Answered By - Marcin Grzejszczak
Answer Checked By - Pedro (JavaFixing Volunteer)