okhttp无法打印traceId 使用opentracing和jaeger框架

问题描述

在开发中,使用okhttp起websocket,打印日志中无法打印traceId和spanId,导致生产问题无法排查

OkHttpClient client = new OkHttpClient.Builder().build();
client.newWebSocket(request, new WebSocketListener() {
	// do something
}

解决方法

经过多次尝试后,使用了一种比较简单的方法解决了。
整体思路是,使用okhttp自带的interceptor,自定义自己的拦截器,在拦截器中放入traceId等信息。

  • 首先是项目启动类
@Configuration
public class OpenTracingConfig {

    @Value("${spring.application.name}")
    private String serviceName;

    @Value("${jager.host}")
    private String jagerHost;

    @Bean
    public io.opentracing.Tracer tracer() {
        JaegerTracer.Builder builder = new JaegerTracer.Builder(serviceName);
        builder.withReporter(new RemoteReporter.Builder().withSender(new UdpSender(jagerHost, 6831, 65000)).build());
        builder.withSampler(new ProbabilisticSampler(1.0));
        builder.withScopeManager(new WrappedThreadLocalScopeManager());
        return builder.build();
    }

    class WrappedThreadLocalScopeManager extends ThreadLocalScopeManager {
        @Override
        public Scope activate(Span span, boolean finishOnClose) {
            if (span != null) {
                String traceContext = span.context().toString();
                if (traceContext != null) {
                    String[] traceInfo = traceContext.split(":");
                    if (traceInfo.length == 4) {
                        // 在打印日志中加入traceId spanId parentSpanId
                        MDC.put("X-B3-TraceId", traceInfo[0]);
                        MDC.put("X-B3-SpanId", traceInfo[1]);
                        MDC.put("X-B3-ParentSpanId", traceInfo[2]);
                    }
                }
            }
            return super.activate(span, finishOnClose);
        }
    }
}
  • 在外部获取traceId等信息,在拦截器中手动放入信息
public class OkHttpTraceInterceptor implements Interceptor {

    /**
     * traceId
     */
    private final String traceId;
    /**
     * spanId
     */
    private final String spanId;
    /**
     * parentSpanId
     */
    private final String parentSpanId;

    public OkHttpTraceInterceptor(String traceId, String spanId, String parentSpanId) {
        this.traceId = traceId;
        this.spanId = spanId;
        this.parentSpanId = parentSpanId;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
    	// 这边有尝试过注入tracer,或者外部获取tracer传入到拦截器,都无法获取到traceId,
    	// 所以无奈只能外部获取具体值,传入拦截器,希望知道的大佬指点下是为什么
   		// JaegerTracer tracer= SpringContextHolder.getBean("tracer");
        // SpanContext context = tracer.activeSpan().context(); // 这里的activeSpan()获取到的是null
   
        //手动放入traceid spanid parentspanid
        MDC.put("X-B3-TraceId", traceId);
        MDC.put("X-B3-SpanId", spanId);
        MDC.put("X-B3-ParentSpanId", parentSpanId);
        
        return chain.proceed(chain.request());
    }
}
  • 构建okhttp传入拦截器参数
OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new OkHttpTraceInterceptor(MDC.get("X-B3-TraceId"), MDC.get("X-B3-SpanId"), MDC.get("X-B3-ParentSpanId")))
                .build();

本次解决只是为了解决问题而解决,并没有了解opentracing的原理,例如为什么在OkHttpTraceInterceptor拦截器中获取tracer的activeSpan(),始终是空,或者在OkHttpTraceInterceptor拦截器中直接用MDC.get(“X-B3-TraceId”)也是空,希望明白的大佬能指点一下!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值