内容简介:之前一篇文章中说到当我们放弃
之前一篇文章中说到当我们放弃 spring-cloud-sleuth 这个组件时,会面临两个问题。首先是日志中无法显示traceId和spanId这些链路信息,其次是不能在用 spring-cloud-sleuth 所提供的方式进行链路传值。现在就让我们来解决这两个问题。上篇回顾
2、日志显示traceId
spring-cloud-sleuth 是将traceId等链路信息保存在 slf4j 的MDC(Mapped Diagnostic Contexts)中,然后通过%X{traceId}这种方式将traceId提取出来,比如打印到控制台的默认格式是:
%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(%5p [${spring.application.name:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
复制代码
opentracing 中提供了 ThreadLocalScopeManager 这个类来管理调用上下文中的Span,我们可以继承该类将traceId设置到MDC中。
public class MDCScopeManager extends ThreadLocalScopeManager {
@Override
public Scope activate(Span span, boolean finishOnClose) {
return new ScopeWrapper(super.activate(span, finishOnClose));
}
@Override
public Scope activate(Span span) {
return new ScopeWrapper(super.activate(span));
}
private static class ScopeWrapper implements Scope {
private final Scope scope;
private final String previousTraceId;
private final String previousSpanId;
private final String previousParentSpanId;
private final String previousSampled;
ScopeWrapper(Scope scope) {
this.scope = scope;
this.previousTraceId = lookup("traceId");
this.previousSpanId = lookup("spanId");
this.previousParentSpanId = lookup("parentSpanId");
this.previousSampled = lookup("traceSampled");
JaegerSpanContext ctx = (JaegerSpanContext) scope.span().context();
String traceId = ctx.getTraceId();
String spanId = Long.toHexString(ctx.getSpanId());
String sampled = String.valueOf(ctx.isSampled());
String parentSpanId = Long.toHexString(ctx.getParentId());
replace("traceId", traceId);
replace("spanId", spanId);
replace("parentSpanId", parentSpanId);
replace("traceSampled", sampled);
}
@Override
public void close() {
this.scope.close();
replace("traceId", previousTraceId);
replace("spanId", previousSpanId);
replace("parentSpanId", previousParentSpanId);
replace("traceSampled", previousSampled);
}
@Override
public Span span() {
return this.scope.span();
}
}
private static String lookup(String key) {
return MDC.get(key);
}
private static void replace(String key, String value) {
if (value == null) {
MDC.remove(key);
} else {
MDC.put(key, value);
}
}
}
复制代码
然后把这个类定义成Bean,这样就能把它绑定到当前的tracer中去:
@Bean
public TracerBuilderCustomizer mdcBuilderCustomizer() {
return builder -> builder.withScopeManager(new MDCScopeManager());
}
复制代码
然后利用 %X{traceId} 这种方式设置打印格式,启动程序后就能在控制台中看到输出了:
是不是和 spring-cloud-sleuth 提供的方式一样~~~
3、跨服务传值
opentracing 中提供了baggage元素来做跨进程的kv传递,我们可以利用baggage来传递我们需要传递的值。(注意:同时他也会产生巨大的开销,请小心使用此特性)
public class TraceContext {
public static void setField(String key, String value) {
if (GlobalTracer.isRegistered() && StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
Tracer tracer = GlobalTracer.get();
tracer.activeSpan().setBaggageItem(key, value);
}
}
public static String getFiled(String key, String defaultValue) {
if (GlobalTracer.isRegistered() && StringUtils.isNotBlank(key)) {
Tracer tracer = GlobalTracer.get();
return tracer.activeSpan().getBaggageItem(key);
}
return defaultValue;
}
}
复制代码
4、多线程中的trace
项目中需要依赖 opentracing-concurrent :
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-concurrent</artifactId>
<version>0.4.0</version>
</dependency>
复制代码
然后可以通过 TraceRunnable 来创建带有trace的线程
new Thread(new TracedRunnable(() -> {
//线程中干活....
}, GlobalTracer.get()));
复制代码
Spring环境中也可以用 @Autowired 来获取tracer
@Autowired private Tracer tracer; 复制代码
以上所述就是小编给大家介绍的《SpringCloud项目接入Jaeger(下)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 原有 Vue 项目接入 TypeScript
- Go项目简单接入travis ci
- vue项目接入微信JSSDK的坑
- 教你在 Node.js 项目中接入 Sign with Apple 第三方登录
- 云转码接入视频网站解决方案 express-ffmpeg接入discuz方案
- 数据接入治理平台
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
突破——程序员如何练就领导力
刘朋 / 电子工业出版社 / 2018-8-31 / 55.00元
内容简介: 在今日中国如雨后春笋般出现的各种新兴的互联网和软件公司中,有越来越多的技术达人凭借在技术上的优异表现而被晋升为技术团队的管理者和领导者。然而,从技术到管理——从单枪匹马的个人贡献者到一呼百应的技术团队领导者——注定是“惊险的一跃”。对于刚走上技术团队管理岗位的技术专家,你一定遇到过和本书作者当年一样的各种困惑和不适“症状”: ——我能处理好人“机”关系,但是如何处理好人际关......一起来看看 《突破——程序员如何练就领导力》 这本书的介绍吧!