博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringCloud项目接入Jaeger(下)
阅读量:6081 次
发布时间:2019-06-20

本文共 4050 字,大约阅读时间需要 13 分钟。

1、上篇回顾

之前一篇文章中说到当我们放弃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中提供了这个类来管理调用上下文中的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中去:

@Beanpublic 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

io.opentracing.contrib
opentracing-concurrent
0.4.0
复制代码

然后可以通过TraceRunnable来创建带有trace的线程

new Thread(new TracedRunnable(() -> {	//线程中干活....	}, GlobalTracer.get()));复制代码

Spring环境中也可以用@Autowired来获取tracer

@Autowiredprivate Tracer tracer;复制代码

转载于:https://juejin.im/post/5d0afbaa51882533e13376ac

你可能感兴趣的文章
开发规范浅谈
查看>>
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
查看>>
鼠标增强软件StrokeIt使用方法
查看>>
本地连接linux虚拟机的方法
查看>>
某公司面试java试题之【二】,看看吧,说不定就是你将要做的题
查看>>
BABOK - 企业分析(Enterprise Analysis)概要
查看>>
Linux 配置vnc,开启linux远程桌面
查看>>
NLog文章系列——如何优化日志性能
查看>>
Hadoop安装测试简单记录
查看>>
CentOS6.4关闭触控板
查看>>
ThreadPoolExecutor线程池运行机制分析-线程复用原理
查看>>
React Native 极光推送填坑(ios)
查看>>
Terratest:一个用于自动化基础设施测试的开源Go库
查看>>
修改Windows远程终端默认端口,让服务器更安全
查看>>
扩展器必须,SAS 2.0未必(SAS挺进中端存储系统之三)
查看>>
Eclipse遇到Initializing Java Tooling解决办法
查看>>
while((ch = getchar()) != '\n')
查看>>
好程序员web前端分享JS检查浏览器类型和版本
查看>>
Oracle DG 逻辑Standby数据同步性能优化
查看>>
exchange 2010 队列删除
查看>>