开放式跟踪未显示跨度之间的关系

问题描述

我正在尝试使用开放式跟踪来显示2个跨度之间的跟踪和关系。

从以下实现中,我期望跟踪的结构如下。

spanOne (parent)
    spanTwo (child)

相反,我最终在两个之间没有任何关系,每个都有自己的块。

spanOne

spanTwo

实施

只是一个界面

@FunctionalInterface
public interface AddData {
    Single<Response> add(Request request);
}

实现上述接口的第一类

import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.Tracer;
import rx.Single;

public class AddDataClassOne implements AddData {

    private final String name;
    private final Tracer tracer;

    public AddDataClassOne(String name,Tracer tracer) {
        this.name = name;
        this.tracer = tracer;
    }

    @Override
    public Single<Response> add(Request request) {

        final Span span = this.tracer.buildSpan(this.name).start();
        try(Scope ignored = this.tracer.scopeManager().activate(span)) {
            // some other logic
            return Single.just(new Response());
        } finally {
            span.finish();
        }
    }
}

实现上述接口的第二类(与第一类相同),删除了其他逻辑以保持简单性

import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.Tracer;
import rx.Single;

public class AddDataClasstwo implements AddData {

    private final String name;
    private final Tracer tracer;

    public AddDataClasstwo(String name,Tracer tracer) {
        this.name = name;
        this.tracer = tracer;
    }

    @Override
    public Single<Response> add(Request request) {

        final Span span = this.tracer.buildSpan(this.name).start();
        try(Scope ignored = this.tracer.scopeManager().activate(span)) {
            // some other logic
            return Single.just(new Response());
        } finally {
            span.finish();
        }
    }
}

主类,我将父类包装在子类上并调用add方法

import io.jaegertracing.internal.JaegerTracer;
import io.jaegertracing.internal.samplers.ConstSampler;
import io.opentracing.Tracer;

import java.util.function.UnaryOperator;

public class MainClass {

    private static final Tracer tracer = new JaegerTracer.Builder("sample-test")
            .withSampler(new ConstSampler(true))
            .build();

    public static void main(String[] args) {

        UnaryOperator<AddData> operator = addData -> new AddDataClassOne("spanOne",tracer);
        AddDataClasstwo addDataClasstwo = new AddDataClasstwo("spanTwo",tracer);

        AddData apply = operator.apply(addDataClasstwo);
        apply.add(new Request()).subscribe();
    }
}

从文档中

如果已经有一个活动跨度,它将充当buildSpan()创建的跨度的父级。

根据给出的示例,每个逻辑在try块中捕获到的跨度名称都与自己的跨度名称相同 在这里做。

参考此页: 此页面上的最后一部分:传播进程内上下文 https://github.com/yurishkuro/opentracing-tutorial/tree/master/java/src/main/java/lesson02

我可以就缺少的内容获得一些建议吗?谢谢。

解决方法

据我所知,原因是执行AddDataClassOne.add() span之后已经完成,因此它不能有任何子span。

因此,在AddDataClassTwo.add中调用start()时,它找不到活动范围,也无法成为其子级。

为了获得所需的结构,必须在致电AddDataClassTwo.add之前先致电span.finish()

注意:应该始终首先关闭嵌套最深的跨度,然后再关闭最初打开的跨度-父级。