spring-cloud - Spring Sleuth 升级并添加自定义跟踪 ID
问题描述
我一直在尝试将我的 Spring Cloud Sleuth 从版本 1.3.3-Release 升级到 2.2.0-Release。我们使用的 HTTPSpanInjector 和 HTTPSpanExtractor 已被弃用。我已经粘贴了需要升级的当前代码
我有一个名为 Tracing Handler 的类
/**
*
*/
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.SpanTextMap;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.web.HttpSpanExtractor;
import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector;
import org.springframework.cloud.sleuth.instrument.web.ZipkinHttpSpanInjector;
import org.springframework.cloud.sleuth.util.TextMapUtil;
import org.springframework.web.filter.GenericFilterBean;
/**
*
*
*/
public final class TracingHandler {
public static final String TRACE_HEADER_NAME = "X-Pep-TraceId";
public static final String SPAN_HEADER_NAME = "X-Pep-SpanId";
public static class CustomHttpSpanExtractor implements HttpSpanExtractor {
@Override
public Span joinTrace(SpanTextMap carrier) {
Map<String, String> map = TextMapUtil.asMap(carrier);
String traceIdStr = map.get(TRACE_HEADER_NAME);
String spanIdStr = map.get(SPAN_HEADER_NAME);
Long traceId = null;
Long spanId = null;
if (!StringUtils.isBlank(traceIdStr)) {
traceId = Span.hexToId(traceIdStr);
}
if (!StringUtils.isBlank(spanIdStr)) {
spanId = Span.hexToId(spanIdStr);
}
Span.SpanBuilder builder = Span.builder();
if (traceId != null) {
builder.traceId(traceId);
}
if (spanId != null) {
builder.spanId(spanId);
}
return builder.build();
}
}
public static class CustomHttpSpanInjector implements HttpSpanInjector {
@Override
public void inject(Span span, SpanTextMap carrier) {
carrier.put(TRACE_HEADER_NAME, span.traceIdString());
carrier.put(SPAN_HEADER_NAME, Span.idToHex(span.getSpanId()));
}
}
static class CustomHttpServletResponseSpanInjector extends ZipkinHttpSpanInjector {
@Override
public void inject(Span span, SpanTextMap carrier) {
super.inject(span, carrier);
carrier.put(Span.TRACE_ID_NAME, span.traceIdString());
carrier.put(Span.SPAN_ID_NAME, Span.idToHex(span.getSpanId()));
}
}
public static class HttpResponseInjectingTraceFilter extends GenericFilterBean {
private final Tracer tracer;
private final HttpSpanInjector spanInjector;
public HttpResponseInjectingTraceFilter(Tracer tracer, HttpSpanInjector spanInjector) {
this.tracer = tracer;
this.spanInjector = spanInjector;
}
@Override
public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
Span currentSpan = this.tracer.getCurrentSpan();
this.spanInjector.inject(currentSpan, new HttpServletResponseTextMap(response));
filterChain.doFilter(request, response);
}
class HttpServletResponseTextMap implements SpanTextMap {
private final HttpServletResponse delegate;
HttpServletResponseTextMap(HttpServletResponse delegate) {
this.delegate = delegate;
}
@Override
public Iterator<Map.Entry<String, String>> iterator() {
Map<String, String> map = new HashMap<>();
for (String header : this.delegate.getHeaderNames()) {
map.put(header, this.delegate.getHeader(header));
}
return map.entrySet().iterator();
}
@Override
public void put(String key, String value) {
this.delegate.addHeader(key, value);
}
}
}
/* As this class is supposed to be a config. class, there's no need to allow consumers to create an object for this class */
private TracingHandler() {}
}
我们在网关微服务中添加跨度,其他微服务只有这样的 bean 定义
@Bean
public HttpSpanInjector customHttpSpanInjector() {
return new TracingHandler.CustomHttpSpanInjector();
}
@Bean
public HttpSpanExtractor customHttpSpanExtractor() {
return new TracingHandler.CustomHttpSpanExtractor();
}
@Bean
public HttpResponseInjectingTraceFilter responseInjectingTraceFilter(Tracer tracer) {
return new HttpResponseInjectingTraceFilter(tracer, customHttpSpanInjector());
}
如何升级到 Spring-Cloud-Sleuth 2.2-Release 并实现相同的功能
解决方案
推荐阅读
- unity3d - 适应不同屏幕尺寸的问题
- python - 如何在python中使用for循环读取多值库
- sql - 通过乘法将一列中的数据合并为一列
- python - 使用python在3D图中绘制骨架点
- reactjs - 如何在反应表中将数据作为参数传递?
- spring - 在类路径资源中定义名称为“springApplicationAdminRegistrar”的 bean 创建错误
- angular - Angular Material Theme - BODY 标签上的选择器
- r - renv::restore() 非常慢
- python - 如何使用 Chaquopy 对 Android 的 python 脚本进行cythonize?
- performance - ResolveRequestCache 状态需要很长时间