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