1 // Copyright 2020, OpenCensus 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 15 package trace 16 17 import ( 18 "context" 19 ) 20 21 // DefaultTracer is the tracer used when package-level exported functions are invoked. 22 var DefaultTracer Tracer = &tracer{} 23 24 // Tracer can start spans and access context functions. 25 type Tracer interface { 26 27 // StartSpan starts a new child span of the current span in the context. If 28 // there is no span in the context, creates a new trace and span. 29 // 30 // Returned context contains the newly created span. You can use it to 31 // propagate the returned span in process. 32 StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) 33 34 // StartSpanWithRemoteParent starts a new child span of the span from the given parent. 35 // 36 // If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is 37 // preferred for cases where the parent is propagated via an incoming request. 38 // 39 // Returned context contains the newly created span. You can use it to 40 // propagate the returned span in process. 41 StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) 42 43 // FromContext returns the Span stored in a context, or nil if there isn't one. 44 FromContext(ctx context.Context) *Span 45 46 // NewContext returns a new context with the given Span attached. 47 NewContext(parent context.Context, s *Span) context.Context 48 } 49 50 // StartSpan starts a new child span of the current span in the context. If 51 // there is no span in the context, creates a new trace and span. 52 // 53 // Returned context contains the newly created span. You can use it to 54 // propagate the returned span in process. 55 func StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) { 56 return DefaultTracer.StartSpan(ctx, name, o...) 57 } 58 59 // StartSpanWithRemoteParent starts a new child span of the span from the given parent. 60 // 61 // If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is 62 // preferred for cases where the parent is propagated via an incoming request. 63 // 64 // Returned context contains the newly created span. You can use it to 65 // propagate the returned span in process. 66 func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) { 67 return DefaultTracer.StartSpanWithRemoteParent(ctx, name, parent, o...) 68 } 69 70 // FromContext returns the Span stored in a context, or a Span that is not 71 // recording events if there isn't one. 72 func FromContext(ctx context.Context) *Span { 73 return DefaultTracer.FromContext(ctx) 74 } 75 76 // NewContext returns a new context with the given Span attached. 77 func NewContext(parent context.Context, s *Span) context.Context { 78 return DefaultTracer.NewContext(parent, s) 79 } 80 81 // SpanInterface represents a span of a trace. It has an associated SpanContext, and 82 // stores data accumulated while the span is active. 83 // 84 // Ideally users should interact with Spans by calling the functions in this 85 // package that take a Context parameter. 86 type SpanInterface interface { 87 88 // IsRecordingEvents returns true if events are being recorded for this span. 89 // Use this check to avoid computing expensive annotations when they will never 90 // be used. 91 IsRecordingEvents() bool 92 93 // End ends the span. 94 End() 95 96 // SpanContext returns the SpanContext of the span. 97 SpanContext() SpanContext 98 99 // SetName sets the name of the span, if it is recording events. 100 SetName(name string) 101 102 // SetStatus sets the status of the span, if it is recording events. 103 SetStatus(status Status) 104 105 // AddAttributes sets attributes in the span. 106 // 107 // Existing attributes whose keys appear in the attributes parameter are overwritten. 108 AddAttributes(attributes ...Attribute) 109 110 // Annotate adds an annotation with attributes. 111 // Attributes can be nil. 112 Annotate(attributes []Attribute, str string) 113 114 // Annotatef adds an annotation with attributes. 115 Annotatef(attributes []Attribute, format string, a ...interface{}) 116 117 // AddMessageSendEvent adds a message send event to the span. 118 // 119 // messageID is an identifier for the message, which is recommended to be 120 // unique in this span and the same between the send event and the receive 121 // event (this allows to identify a message between the sender and receiver). 122 // For example, this could be a sequence id. 123 AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) 124 125 // AddMessageReceiveEvent adds a message receive event to the span. 126 // 127 // messageID is an identifier for the message, which is recommended to be 128 // unique in this span and the same between the send event and the receive 129 // event (this allows to identify a message between the sender and receiver). 130 // For example, this could be a sequence id. 131 AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) 132 133 // AddLink adds a link to the span. 134 AddLink(l Link) 135 136 // String prints a string representation of a span. 137 String() string 138 } 139 140 // NewSpan is a convenience function for creating a *Span out of a *span 141 func NewSpan(s SpanInterface) *Span { 142 return &Span{internal: s} 143 } 144 145 // Span is a struct wrapper around the SpanInt interface, which allows correctly handling 146 // nil spans, while also allowing the SpanInterface implementation to be swapped out. 147 type Span struct { 148 internal SpanInterface 149 } 150 151 // Internal returns the underlying implementation of the Span 152 func (s *Span) Internal() SpanInterface { 153 return s.internal 154 } 155 156 // IsRecordingEvents returns true if events are being recorded for this span. 157 // Use this check to avoid computing expensive annotations when they will never 158 // be used. 159 func (s *Span) IsRecordingEvents() bool { 160 if s == nil { 161 return false 162 } 163 return s.internal.IsRecordingEvents() 164 } 165 166 // End ends the span. 167 func (s *Span) End() { 168 if s == nil { 169 return 170 } 171 s.internal.End() 172 } 173 174 // SpanContext returns the SpanContext of the span. 175 func (s *Span) SpanContext() SpanContext { 176 if s == nil { 177 return SpanContext{} 178 } 179 return s.internal.SpanContext() 180 } 181 182 // SetName sets the name of the span, if it is recording events. 183 func (s *Span) SetName(name string) { 184 if !s.IsRecordingEvents() { 185 return 186 } 187 s.internal.SetName(name) 188 } 189 190 // SetStatus sets the status of the span, if it is recording events. 191 func (s *Span) SetStatus(status Status) { 192 if !s.IsRecordingEvents() { 193 return 194 } 195 s.internal.SetStatus(status) 196 } 197 198 // AddAttributes sets attributes in the span. 199 // 200 // Existing attributes whose keys appear in the attributes parameter are overwritten. 201 func (s *Span) AddAttributes(attributes ...Attribute) { 202 if !s.IsRecordingEvents() { 203 return 204 } 205 s.internal.AddAttributes(attributes...) 206 } 207 208 // Annotate adds an annotation with attributes. 209 // Attributes can be nil. 210 func (s *Span) Annotate(attributes []Attribute, str string) { 211 if !s.IsRecordingEvents() { 212 return 213 } 214 s.internal.Annotate(attributes, str) 215 } 216 217 // Annotatef adds an annotation with attributes. 218 func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) { 219 if !s.IsRecordingEvents() { 220 return 221 } 222 s.internal.Annotatef(attributes, format, a...) 223 } 224 225 // AddMessageSendEvent adds a message send event to the span. 226 // 227 // messageID is an identifier for the message, which is recommended to be 228 // unique in this span and the same between the send event and the receive 229 // event (this allows to identify a message between the sender and receiver). 230 // For example, this could be a sequence id. 231 func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) { 232 if !s.IsRecordingEvents() { 233 return 234 } 235 s.internal.AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize) 236 } 237 238 // AddMessageReceiveEvent adds a message receive event to the span. 239 // 240 // messageID is an identifier for the message, which is recommended to be 241 // unique in this span and the same between the send event and the receive 242 // event (this allows to identify a message between the sender and receiver). 243 // For example, this could be a sequence id. 244 func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) { 245 if !s.IsRecordingEvents() { 246 return 247 } 248 s.internal.AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize) 249 } 250 251 // AddLink adds a link to the span. 252 func (s *Span) AddLink(l Link) { 253 if !s.IsRecordingEvents() { 254 return 255 } 256 s.internal.AddLink(l) 257 } 258 259 // String prints a string representation of a span. 260 func (s *Span) String() string { 261 if s == nil { 262 return "<nil>" 263 } 264 return s.internal.String() 265 } 266