[英]Spring cloud sleuth 3.0.1 generate traceid & spanid in logs using logback
[英]Not able to pass Sleuth traceid and spanid to downstream services while making API calls using resttemplate with new keyword
目前,我正在将 Sleuth 集成到我们现有的微服务中以增强日志记录机制。 MS 使用 Spring Boot 2.5.6 和 Spring Cloud 2020.0.6 构建(已解决为 Spring Cloud Sleuth 3.0)。
我试图解决的挑战是在进行出站 API 调用时,我们使用 new() 关键字创建 RestTemplate,而不是将 RestTemplate 作为 Bean 管理。 不幸的是,我们无权更改使用 resttemplate 作为 Bean 的方法,以使 Sleuth 和 Brave 工具无缝工作(以避免在应用程序中引入任何重大更改)以将 traceid 传播到下游日志(如前所述在官方文档中)。 因此,MS1 和 MS2 日志中的 traceid 不同,这使得跟踪变得困难。
正如我从官方文档中了解到的那样,Brave 将拦截器注册为喜欢 LazyTraceClientHttpRequestInterceptor 和 TracingClientHttpRequestInterceptor 以将 X-B3-Traceid、X-B3-SpanId 等标头添加到出站请求中,我尝试做类似的事情。
这是我的自定义拦截器的代码:
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;
}
}
在我的 controller class 中,我已经自动连接了这个拦截器:
@Autowired
private RequestResponseLoggingInterceptor interceptor;
并使用此拦截器进行 resttemplate 调用,如下所示:
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(interceptor));
ResponseEntity<ProductSale> responseEntity = restTemplate.getForEntity(
"http://localhost:8000/product-service/pname/{pname}/cost/{cost}/qty/{qty}", ProductSale.class,
uriVariables);
ProductSale sales = responseEntity.getBody();
当我比较这个 API 调用的 MS1 和 MS2 日志时,traceid 是不同的。
谁能帮我我在这里做错了什么? 以及如何通过使用 New() 关键字创建 RestTemplate 来实现向下游服务的 traceid 传播。
我和 Sleuth 合作的不多,但我对每次创建一个新的 RestTemplate 都有很大的怀疑。
尝试使用 singleton scope 将其定义为 bean,然后自动装配 RestTemplate。
您需要将TracingClientHttpRequestInterceptor
bean 注入到您的 rest 模板中,它将负责传递跟踪上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.