1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3 4 package trace // import "go.opentelemetry.io/otel/trace"
5 6 import (
7 "time"
8 9 "go.opentelemetry.io/otel/attribute"
10 )
11 12 // TracerConfig is a group of options for a Tracer.
13 type 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.
21 func (t *TracerConfig) InstrumentationVersion() string {
22 return t.instrumentationVersion
23 }
24 25 // InstrumentationAttributes returns the attributes associated with the library
26 // providing instrumentation.
27 func (t *TracerConfig) InstrumentationAttributes() attribute.Set {
28 return t.attrs
29 }
30 31 // SchemaURL returns the Schema URL of the telemetry emitted by the Tracer.
32 func (t *TracerConfig) SchemaURL() string {
33 return t.schemaURL
34 }
35 36 // NewTracerConfig applies all the options to a returned TracerConfig.
37 func 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.
46 type TracerOption interface {
47 apply(TracerConfig) TracerConfig
48 }
49 50 type tracerOptionFunc func(TracerConfig) TracerConfig
51 52 func (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig {
53 return fn(cfg)
54 }
55 56 // SpanConfig is a group of options for a Span.
57 type 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.
67 func (cfg *SpanConfig) Attributes() []attribute.KeyValue {
68 return cfg.attributes
69 }
70 71 // Timestamp is a time in a Span life-cycle.
72 func (cfg *SpanConfig) Timestamp() time.Time {
73 return cfg.timestamp
74 }
75 76 // StackTrace reports whether stack trace capturing is enabled.
77 func (cfg *SpanConfig) StackTrace() bool {
78 return cfg.stackTrace
79 }
80 81 // Links are the associations a Span has with other Spans.
82 func (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.
89 func (cfg *SpanConfig) NewRoot() bool {
90 return cfg.newRoot
91 }
92 93 // SpanKind is the role a Span has in a trace.
94 func (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.
102 func 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.
114 func 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.
124 type SpanStartOption interface {
125 applySpanStart(SpanConfig) SpanConfig
126 }
127 128 type spanOptionFunc func(SpanConfig) SpanConfig
129 130 func (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.
136 type SpanEndOption interface {
137 applySpanEnd(SpanConfig) SpanConfig
138 }
139 140 // EventConfig is a group of options for an Event.
141 type EventConfig struct {
142 attributes []attribute.KeyValue
143 timestamp time.Time
144 stackTrace bool
145 }
146 147 // Attributes describe the associated qualities of an Event.
148 func (cfg *EventConfig) Attributes() []attribute.KeyValue {
149 return cfg.attributes
150 }
151 152 // Timestamp is a time in an Event life-cycle.
153 func (cfg *EventConfig) Timestamp() time.Time {
154 return cfg.timestamp
155 }
156 157 // StackTrace reports whether stack trace capturing is enabled.
158 func (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.
166 func 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.
178 type 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.
183 type 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.
189 type 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.
195 type SpanEndEventOption interface {
196 SpanEndOption
197 EventOption
198 }
199 200 type attributeOption []attribute.KeyValue
201 202 func (o attributeOption) applySpan(c SpanConfig) SpanConfig {
203 c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
204 return c
205 }
206 func (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
207 func (o attributeOption) applyEvent(c EventConfig) EventConfig {
208 c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
209 return c
210 }
211 212 var _ 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.
223 func 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.
228 type SpanEventOption interface {
229 SpanOption
230 EventOption
231 }
232 233 type timestampOption time.Time
234 235 func (o timestampOption) applySpan(c SpanConfig) SpanConfig {
236 c.timestamp = time.Time(o)
237 return c
238 }
239 func (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
240 func (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }
241 func (o timestampOption) applyEvent(c EventConfig) EventConfig {
242 c.timestamp = time.Time(o)
243 return c
244 }
245 246 var _ SpanEventOption = timestampOption{}
247 248 // WithTimestamp sets the time of a Span or Event life-cycle moment (e.g.
249 // started, stopped, errored).
250 func WithTimestamp(t time.Time) SpanEventOption {
251 return timestampOption(t)
252 }
253 254 type stackTraceOption bool
255 256 func (o stackTraceOption) applyEvent(c EventConfig) EventConfig {
257 c.stackTrace = bool(o)
258 return c
259 }
260 261 func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {
262 c.stackTrace = bool(o)
263 return c
264 }
265 func (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).
268 func 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.
274 func 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.
284 func 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.
292 func 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.
300 func 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.
310 func 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.
318 func WithSchemaURL(schemaURL string) TracerOption {
319 return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
320 cfg.schemaURL = schemaURL
321 return cfg
322 })
323 }
324