1// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4package trace // import "go.opentelemetry.io/otel/trace"
5
6import (
7 "time"
8
9 "go.opentelemetry.io/otel/attribute"
10)
11
12// TracerConfig is a group of options for a Tracer.
13type TracerConfig struct {
14 instrumentationVersion string
15 // Schema URL of the telemetry emitted by the Tracer.
16 schemaURL string
17 attrs attribute.Set
18}
19
20// InstrumentationVersion returns the version of the library providing instrumentation.
21func (t *TracerConfig) InstrumentationVersion() string {
22 return t.instrumentationVersion
23}
24
25// InstrumentationAttributes returns the attributes associated with the library
26// providing instrumentation.
27func (t *TracerConfig) InstrumentationAttributes() attribute.Set {
28 return t.attrs
29}
30
31// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer.
32func (t *TracerConfig) SchemaURL() string {
33 return t.schemaURL
34}
35
36// NewTracerConfig applies all the options to a returned TracerConfig.
37func NewTracerConfig(options ...TracerOption) TracerConfig {
38 var config TracerConfig
39 for _, option := range options {
40 config = option.apply(config)
41 }
42 return config
43}
44
45// TracerOption applies an option to a TracerConfig.
46type TracerOption interface {
47 apply(TracerConfig) TracerConfig
48}
49
50type tracerOptionFunc func(TracerConfig) TracerConfig
51
52func (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig {
53 return fn(cfg)
54}
55
56// SpanConfig is a group of options for a Span.
57type SpanConfig struct {
58 attributes []attribute.KeyValue
59 timestamp time.Time
60 links []Link
61 newRoot bool
62 spanKind SpanKind
63 stackTrace bool
64}
65
66// Attributes describe the associated qualities of a Span.
67func (cfg *SpanConfig) Attributes() []attribute.KeyValue {
68 return cfg.attributes
69}
70
71// Timestamp is a time in a Span life-cycle.
72func (cfg *SpanConfig) Timestamp() time.Time {
73 return cfg.timestamp
74}
75
76// StackTrace checks whether stack trace capturing is enabled.
77func (cfg *SpanConfig) StackTrace() bool {
78 return cfg.stackTrace
79}
80
81// Links are the associations a Span has with other Spans.
82func (cfg *SpanConfig) Links() []Link {
83 return cfg.links
84}
85
86// NewRoot identifies a Span as the root Span for a new trace. This is
87// commonly used when an existing trace crosses trust boundaries and the
88// remote parent span context should be ignored for security.
89func (cfg *SpanConfig) NewRoot() bool {
90 return cfg.newRoot
91}
92
93// SpanKind is the role a Span has in a trace.
94func (cfg *SpanConfig) SpanKind() SpanKind {
95 return cfg.spanKind
96}
97
98// NewSpanStartConfig applies all the options to a returned SpanConfig.
99// No validation is performed on the returned SpanConfig (e.g. no uniqueness
100// checking or bounding of data), it is left to the SDK to perform this
101// action.
102func NewSpanStartConfig(options ...SpanStartOption) SpanConfig {
103 var c SpanConfig
104 for _, option := range options {
105 c = option.applySpanStart(c)
106 }
107 return c
108}
109
110// NewSpanEndConfig applies all the options to a returned SpanConfig.
111// No validation is performed on the returned SpanConfig (e.g. no uniqueness
112// checking or bounding of data), it is left to the SDK to perform this
113// action.
114func NewSpanEndConfig(options ...SpanEndOption) SpanConfig {
115 var c SpanConfig
116 for _, option := range options {
117 c = option.applySpanEnd(c)
118 }
119 return c
120}
121
122// SpanStartOption applies an option to a SpanConfig. These options are applicable
123// only when the span is created.
124type SpanStartOption interface {
125 applySpanStart(SpanConfig) SpanConfig
126}
127
128type spanOptionFunc func(SpanConfig) SpanConfig
129
130func (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig {
131 return fn(cfg)
132}
133
134// SpanEndOption applies an option to a SpanConfig. These options are
135// applicable only when the span is ended.
136type SpanEndOption interface {
137 applySpanEnd(SpanConfig) SpanConfig
138}
139
140// EventConfig is a group of options for an Event.
141type EventConfig struct {
142 attributes []attribute.KeyValue
143 timestamp time.Time
144 stackTrace bool
145}
146
147// Attributes describe the associated qualities of an Event.
148func (cfg *EventConfig) Attributes() []attribute.KeyValue {
149 return cfg.attributes
150}
151
152// Timestamp is a time in an Event life-cycle.
153func (cfg *EventConfig) Timestamp() time.Time {
154 return cfg.timestamp
155}
156
157// StackTrace checks whether stack trace capturing is enabled.
158func (cfg *EventConfig) StackTrace() bool {
159 return cfg.stackTrace
160}
161
162// NewEventConfig applies all the EventOptions to a returned EventConfig. If no
163// timestamp option is passed, the returned EventConfig will have a Timestamp
164// set to the call time, otherwise no validation is performed on the returned
165// EventConfig.
166func NewEventConfig(options ...EventOption) EventConfig {
167 var c EventConfig
168 for _, option := range options {
169 c = option.applyEvent(c)
170 }
171 if c.timestamp.IsZero() {
172 c.timestamp = time.Now()
173 }
174 return c
175}
176
177// EventOption applies span event options to an EventConfig.
178type EventOption interface {
179 applyEvent(EventConfig) EventConfig
180}
181
182// SpanOption are options that can be used at both the beginning and end of a span.
183type SpanOption interface {
184 SpanStartOption
185 SpanEndOption
186}
187
188// SpanStartEventOption are options that can be used at the start of a span, or with an event.
189type SpanStartEventOption interface {
190 SpanStartOption
191 EventOption
192}
193
194// SpanEndEventOption are options that can be used at the end of a span, or with an event.
195type SpanEndEventOption interface {
196 SpanEndOption
197 EventOption
198}
199
200type attributeOption []attribute.KeyValue
201
202func (o attributeOption) applySpan(c SpanConfig) SpanConfig {
203 c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
204 return c
205}
206func (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
207func (o attributeOption) applyEvent(c EventConfig) EventConfig {
208 c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
209 return c
210}
211
212var _ SpanStartEventOption = attributeOption{}
213
214// WithAttributes adds the attributes related to a span life-cycle event.
215// These attributes are used to describe the work a Span represents when this
216// option is provided to a Span's start event. Otherwise, these
217// attributes provide additional information about the event being recorded
218// (e.g. error, state change, processing progress, system event).
219//
220// If multiple of these options are passed the attributes of each successive
221// option will extend the attributes instead of overwriting. There is no
222// guarantee of uniqueness in the resulting attributes.
223func WithAttributes(attributes ...attribute.KeyValue) SpanStartEventOption {
224 return attributeOption(attributes)
225}
226
227// SpanEventOption are options that can be used with an event or a span.
228type SpanEventOption interface {
229 SpanOption
230 EventOption
231}
232
233type timestampOption time.Time
234
235func (o timestampOption) applySpan(c SpanConfig) SpanConfig {
236 c.timestamp = time.Time(o)
237 return c
238}
239func (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
240func (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }
241func (o timestampOption) applyEvent(c EventConfig) EventConfig {
242 c.timestamp = time.Time(o)
243 return c
244}
245
246var _ SpanEventOption = timestampOption{}
247
248// WithTimestamp sets the time of a Span or Event life-cycle moment (e.g.
249// started, stopped, errored).
250func WithTimestamp(t time.Time) SpanEventOption {
251 return timestampOption(t)
252}
253
254type stackTraceOption bool
255
256func (o stackTraceOption) applyEvent(c EventConfig) EventConfig {
257 c.stackTrace = bool(o)
258 return c
259}
260
261func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {
262 c.stackTrace = bool(o)
263 return c
264}
265func (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }
266
267// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false).
268func WithStackTrace(b bool) SpanEndEventOption {
269 return stackTraceOption(b)
270}
271
272// WithLinks adds links to a Span. The links are added to the existing Span
273// links, i.e. this does not overwrite. Links with invalid span context are ignored.
274func WithLinks(links ...Link) SpanStartOption {
275 return spanOptionFunc(func(cfg SpanConfig) SpanConfig {
276 cfg.links = append(cfg.links, links...)
277 return cfg
278 })
279}
280
281// WithNewRoot specifies that the Span should be treated as a root Span. Any
282// existing parent span context will be ignored when defining the Span's trace
283// identifiers.
284func WithNewRoot() SpanStartOption {
285 return spanOptionFunc(func(cfg SpanConfig) SpanConfig {
286 cfg.newRoot = true
287 return cfg
288 })
289}
290
291// WithSpanKind sets the SpanKind of a Span.
292func WithSpanKind(kind SpanKind) SpanStartOption {
293 return spanOptionFunc(func(cfg SpanConfig) SpanConfig {
294 cfg.spanKind = kind
295 return cfg
296 })
297}
298
299// WithInstrumentationVersion sets the instrumentation version.
300func WithInstrumentationVersion(version string) TracerOption {
301 return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
302 cfg.instrumentationVersion = version
303 return cfg
304 })
305}
306
307// WithInstrumentationAttributes sets the instrumentation attributes.
308//
309// The passed attributes will be de-duplicated.
310func WithInstrumentationAttributes(attr ...attribute.KeyValue) TracerOption {
311 return tracerOptionFunc(func(config TracerConfig) TracerConfig {
312 config.attrs = attribute.NewSet(attr...)
313 return config
314 })
315}
316
317// WithSchemaURL sets the schema URL for the Tracer.
318func WithSchemaURL(schemaURL string) TracerOption {
319 return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
320 cfg.schemaURL = schemaURL
321 return cfg
322 })
323}