| Abhay Kumar | 40252eb | 2025-10-13 13:25:53 +0000 | [diff] [blame^] | 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 checks 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 checks 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 | } |