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 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 is the version of the library providing 26 // instrumentation. 27 InstrumentationVersion string 28} 29 30// NewTracerConfig applies all the options to a returned TracerConfig. 31func NewTracerConfig(options ...TracerOption) *TracerConfig { 32 config := new(TracerConfig) 33 for _, option := range options { 34 option.ApplyTracer(config) 35 } 36 return config 37} 38 39// TracerOption applies an option to a TracerConfig. 40type TracerOption interface { 41 ApplyTracer(*TracerConfig) 42 43 // A private method to prevent users implementing the 44 // interface and so future additions to it will not 45 // violate compatibility. 46 private() 47} 48 49// SpanConfig is a group of options for a Span. 50type SpanConfig struct { 51 // Attributes describe the associated qualities of a Span. 52 Attributes []attribute.KeyValue 53 // Timestamp is a time in a Span life-cycle. 54 Timestamp time.Time 55 // Links are the associations a Span has with other Spans. 56 Links []Link 57 // NewRoot identifies a Span as the root Span for a new trace. This is 58 // commonly used when an existing trace crosses trust boundaries and the 59 // remote parent span context should be ignored for security. 60 NewRoot bool 61 // SpanKind is the role a Span has in a trace. 62 SpanKind SpanKind 63} 64 65// NewSpanConfig applies all the options to a returned SpanConfig. 66// No validation is performed on the returned SpanConfig (e.g. no uniqueness 67// checking or bounding of data), it is left to the SDK to perform this 68// action. 69func NewSpanConfig(options ...SpanOption) *SpanConfig { 70 c := new(SpanConfig) 71 for _, option := range options { 72 option.ApplySpan(c) 73 } 74 return c 75} 76 77// SpanOption applies an option to a SpanConfig. 78type SpanOption interface { 79 ApplySpan(*SpanConfig) 80 81 // A private method to prevent users implementing the 82 // interface and so future additions to it will not 83 // violate compatibility. 84 private() 85} 86 87// NewEventConfig applies all the EventOptions to a returned SpanConfig. If no 88// timestamp option is passed, the returned SpanConfig will have a Timestamp 89// set to the call time, otherwise no validation is performed on the returned 90// SpanConfig. 91func NewEventConfig(options ...EventOption) *SpanConfig { 92 c := new(SpanConfig) 93 for _, option := range options { 94 option.ApplyEvent(c) 95 } 96 if c.Timestamp.IsZero() { 97 c.Timestamp = time.Now() 98 } 99 return c 100} 101 102// EventOption applies span event options to a SpanConfig. 103type EventOption interface { 104 ApplyEvent(*SpanConfig) 105 106 // A private method to prevent users implementing the 107 // interface and so future additions to it will not 108 // violate compatibility. 109 private() 110} 111 112// LifeCycleOption applies span life-cycle options to a SpanConfig. These 113// options set values releated to events in a spans life-cycle like starting, 114// ending, experiencing an error and other user defined notable events. 115type LifeCycleOption interface { 116 SpanOption 117 EventOption 118} 119 120type attributeSpanOption []attribute.KeyValue 121 122func (o attributeSpanOption) ApplySpan(c *SpanConfig) { o.apply(c) } 123func (o attributeSpanOption) ApplyEvent(c *SpanConfig) { o.apply(c) } 124func (attributeSpanOption) private() {} 125func (o attributeSpanOption) apply(c *SpanConfig) { 126 c.Attributes = append(c.Attributes, []attribute.KeyValue(o)...) 127} 128 129// WithAttributes adds the attributes related to a span life-cycle event. 130// These attributes are used to describe the work a Span represents when this 131// option is provided to a Span's start or end events. Otherwise, these 132// attributes provide additional information about the event being recorded 133// (e.g. error, state change, processing progress, system event). 134// 135// If multiple of these options are passed the attributes of each successive 136// option will extend the attributes instead of overwriting. There is no 137// guarantee of uniqueness in the resulting attributes. 138func WithAttributes(attributes ...attribute.KeyValue) LifeCycleOption { 139 return attributeSpanOption(attributes) 140} 141 142type timestampSpanOption time.Time 143 144func (o timestampSpanOption) ApplySpan(c *SpanConfig) { o.apply(c) } 145func (o timestampSpanOption) ApplyEvent(c *SpanConfig) { o.apply(c) } 146func (timestampSpanOption) private() {} 147func (o timestampSpanOption) apply(c *SpanConfig) { c.Timestamp = time.Time(o) } 148 149// WithTimestamp sets the time of a Span life-cycle moment (e.g. started, 150// stopped, errored). 151func WithTimestamp(t time.Time) LifeCycleOption { 152 return timestampSpanOption(t) 153} 154 155type linksSpanOption []Link 156 157func (o linksSpanOption) ApplySpan(c *SpanConfig) { c.Links = append(c.Links, []Link(o)...) } 158func (linksSpanOption) private() {} 159 160// WithLinks adds links to a Span. The links are added to the existing Span 161// links, i.e. this does not overwrite. 162func WithLinks(links ...Link) SpanOption { 163 return linksSpanOption(links) 164} 165 166type newRootSpanOption bool 167 168func (o newRootSpanOption) ApplySpan(c *SpanConfig) { c.NewRoot = bool(o) } 169func (newRootSpanOption) private() {} 170 171// WithNewRoot specifies that the Span should be treated as a root Span. Any 172// existing parent span context will be ignored when defining the Span's trace 173// identifiers. 174func WithNewRoot() SpanOption { 175 return newRootSpanOption(true) 176} 177 178type spanKindSpanOption SpanKind 179 180func (o spanKindSpanOption) ApplySpan(c *SpanConfig) { c.SpanKind = SpanKind(o) } 181func (o spanKindSpanOption) private() {} 182 183// WithSpanKind sets the SpanKind of a Span. 184func WithSpanKind(kind SpanKind) SpanOption { 185 return spanKindSpanOption(kind) 186} 187 188// InstrumentationOption is an interface for applying instrumentation specific 189// options. 190type InstrumentationOption interface { 191 TracerOption 192} 193 194// WithInstrumentationVersion sets the instrumentation version. 195func WithInstrumentationVersion(version string) InstrumentationOption { 196 return instrumentationVersionOption(version) 197} 198 199type instrumentationVersionOption string 200 201func (i instrumentationVersionOption) ApplyTracer(config *TracerConfig) { 202 config.InstrumentationVersion = string(i) 203} 204 205func (instrumentationVersionOption) private() {} 206