otel 源码阅读(三)

2022-03-08  本文已影响0人  迪克dike

Tracer

Tracer的逻辑很简单,Tracer接口就一个Start方法,用来生成新的span。
与之相对于的tracer结构体,可以说是非常简单

type tracer struct {
    provider               *TracerProvider   // 上层的provider
    instrumentationLibrary instrumentation.Library   // 没啥用,可以忽略
}

然后是实现Tracer接口的Start方法

func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) {
    config := trace.NewSpanStartConfig(options...) // 配置

    // 记录从当前span创建的子span的个数(如果是recordingSpan)
    if p := trace.SpanFromContext(ctx); p != nil {
        if sdkSpan, ok := p.(*recordingSpan); ok {
            sdkSpan.addChild()
        }
    }

    s := tr.newSpan(ctx, name, &config) // 从当前携带span信息的ctx创建新的子span
    if rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() {
        sps, _ := tr.provider.spanProcessors.Load().(spanProcessorStates)
        for _, sp := range sps {
            sp.sp.OnStart(ctx, rw)
        }
    }
    if rtt, ok := s.(runtimeTracer); ok {
        ctx = rtt.runtimeTrace(ctx)
    }

    return trace.ContextWithSpan(ctx, s), s
}
上一篇 下一篇

猜你喜欢

热点阅读