...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package trace
16
17 import (
18 "context"
19 "time"
20
21 "go.opentelemetry.io/otel/sdk/instrumentation"
22 "go.opentelemetry.io/otel/trace"
23 "go.opentelemetry.io/otel/trace/embedded"
24 )
25
26 type tracer struct {
27 embedded.Tracer
28
29 provider *TracerProvider
30 instrumentationScope instrumentation.Scope
31 }
32
33 var _ trace.Tracer = &tracer{}
34
35
36
37
38
39
40 func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) {
41 config := trace.NewSpanStartConfig(options...)
42
43 if ctx == nil {
44
45 ctx = context.Background()
46 }
47
48
49 if p := trace.SpanFromContext(ctx); p != nil {
50 if sdkSpan, ok := p.(*recordingSpan); ok {
51 sdkSpan.addChild()
52 }
53 }
54
55 s := tr.newSpan(ctx, name, &config)
56 if rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() {
57 sps := tr.provider.getSpanProcessors()
58 for _, sp := range sps {
59 sp.sp.OnStart(ctx, rw)
60 }
61 }
62 if rtt, ok := s.(runtimeTracer); ok {
63 ctx = rtt.runtimeTrace(ctx)
64 }
65
66 return trace.ContextWithSpan(ctx, s), s
67 }
68
69 type runtimeTracer interface {
70
71
72 runtimeTrace(ctx context.Context) context.Context
73 }
74
75
76 func (tr *tracer) newSpan(ctx context.Context, name string, config *trace.SpanConfig) trace.Span {
77
78
79 var psc trace.SpanContext
80 if config.NewRoot() {
81 ctx = trace.ContextWithSpanContext(ctx, psc)
82 } else {
83 psc = trace.SpanContextFromContext(ctx)
84 }
85
86
87
88
89 var tid trace.TraceID
90 var sid trace.SpanID
91 if !psc.TraceID().IsValid() {
92 tid, sid = tr.provider.idGenerator.NewIDs(ctx)
93 } else {
94 tid = psc.TraceID()
95 sid = tr.provider.idGenerator.NewSpanID(ctx, tid)
96 }
97
98 samplingResult := tr.provider.sampler.ShouldSample(SamplingParameters{
99 ParentContext: ctx,
100 TraceID: tid,
101 Name: name,
102 Kind: config.SpanKind(),
103 Attributes: config.Attributes(),
104 Links: config.Links(),
105 })
106
107 scc := trace.SpanContextConfig{
108 TraceID: tid,
109 SpanID: sid,
110 TraceState: samplingResult.Tracestate,
111 }
112 if isSampled(samplingResult) {
113 scc.TraceFlags = psc.TraceFlags() | trace.FlagsSampled
114 } else {
115 scc.TraceFlags = psc.TraceFlags() &^ trace.FlagsSampled
116 }
117 sc := trace.NewSpanContext(scc)
118
119 if !isRecording(samplingResult) {
120 return tr.newNonRecordingSpan(sc)
121 }
122 return tr.newRecordingSpan(psc, sc, name, samplingResult, config)
123 }
124
125
126 func (tr *tracer) newRecordingSpan(psc, sc trace.SpanContext, name string, sr SamplingResult, config *trace.SpanConfig) *recordingSpan {
127 startTime := config.Timestamp()
128 if startTime.IsZero() {
129 startTime = time.Now()
130 }
131
132 s := &recordingSpan{
133
134
135
136
137
138
139
140
141 parent: psc,
142 spanContext: sc,
143 spanKind: trace.ValidateSpanKind(config.SpanKind()),
144 name: name,
145 startTime: startTime,
146 events: newEvictedQueue(tr.provider.spanLimits.EventCountLimit),
147 links: newEvictedQueue(tr.provider.spanLimits.LinkCountLimit),
148 tracer: tr,
149 }
150
151 for _, l := range config.Links() {
152 s.addLink(l)
153 }
154
155 s.SetAttributes(sr.Attributes...)
156 s.SetAttributes(config.Attributes()...)
157
158 return s
159 }
160
161
162 func (tr *tracer) newNonRecordingSpan(sc trace.SpanContext) nonRecordingSpan {
163 return nonRecordingSpan{tracer: tr, sc: sc}
164 }
165
View as plain text