| // Copyright 2020, OpenCensus Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package trace |
| |
| import ( |
| "context" |
| ) |
| |
| // DefaultTracer is the tracer used when package-level exported functions are invoked. |
| var DefaultTracer Tracer = &tracer{} |
| |
| // Tracer can start spans and access context functions. |
| type Tracer interface { |
| |
| // StartSpan starts a new child span of the current span in the context. If |
| // there is no span in the context, creates a new trace and span. |
| // |
| // Returned context contains the newly created span. You can use it to |
| // propagate the returned span in process. |
| StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) |
| |
| // StartSpanWithRemoteParent starts a new child span of the span from the given parent. |
| // |
| // If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is |
| // preferred for cases where the parent is propagated via an incoming request. |
| // |
| // Returned context contains the newly created span. You can use it to |
| // propagate the returned span in process. |
| StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) |
| |
| // FromContext returns the Span stored in a context, or nil if there isn't one. |
| FromContext(ctx context.Context) *Span |
| |
| // NewContext returns a new context with the given Span attached. |
| NewContext(parent context.Context, s *Span) context.Context |
| } |
| |
| // StartSpan starts a new child span of the current span in the context. If |
| // there is no span in the context, creates a new trace and span. |
| // |
| // Returned context contains the newly created span. You can use it to |
| // propagate the returned span in process. |
| func StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) { |
| return DefaultTracer.StartSpan(ctx, name, o...) |
| } |
| |
| // StartSpanWithRemoteParent starts a new child span of the span from the given parent. |
| // |
| // If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is |
| // preferred for cases where the parent is propagated via an incoming request. |
| // |
| // Returned context contains the newly created span. You can use it to |
| // propagate the returned span in process. |
| func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) { |
| return DefaultTracer.StartSpanWithRemoteParent(ctx, name, parent, o...) |
| } |
| |
| // FromContext returns the Span stored in a context, or a Span that is not |
| // recording events if there isn't one. |
| func FromContext(ctx context.Context) *Span { |
| return DefaultTracer.FromContext(ctx) |
| } |
| |
| // NewContext returns a new context with the given Span attached. |
| func NewContext(parent context.Context, s *Span) context.Context { |
| return DefaultTracer.NewContext(parent, s) |
| } |
| |
| // SpanInterface represents a span of a trace. It has an associated SpanContext, and |
| // stores data accumulated while the span is active. |
| // |
| // Ideally users should interact with Spans by calling the functions in this |
| // package that take a Context parameter. |
| type SpanInterface interface { |
| |
| // IsRecordingEvents returns true if events are being recorded for this span. |
| // Use this check to avoid computing expensive annotations when they will never |
| // be used. |
| IsRecordingEvents() bool |
| |
| // End ends the span. |
| End() |
| |
| // SpanContext returns the SpanContext of the span. |
| SpanContext() SpanContext |
| |
| // SetName sets the name of the span, if it is recording events. |
| SetName(name string) |
| |
| // SetStatus sets the status of the span, if it is recording events. |
| SetStatus(status Status) |
| |
| // AddAttributes sets attributes in the span. |
| // |
| // Existing attributes whose keys appear in the attributes parameter are overwritten. |
| AddAttributes(attributes ...Attribute) |
| |
| // Annotate adds an annotation with attributes. |
| // Attributes can be nil. |
| Annotate(attributes []Attribute, str string) |
| |
| // Annotatef adds an annotation with attributes. |
| Annotatef(attributes []Attribute, format string, a ...interface{}) |
| |
| // AddMessageSendEvent adds a message send event to the span. |
| // |
| // messageID is an identifier for the message, which is recommended to be |
| // unique in this span and the same between the send event and the receive |
| // event (this allows to identify a message between the sender and receiver). |
| // For example, this could be a sequence id. |
| AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) |
| |
| // AddMessageReceiveEvent adds a message receive event to the span. |
| // |
| // messageID is an identifier for the message, which is recommended to be |
| // unique in this span and the same between the send event and the receive |
| // event (this allows to identify a message between the sender and receiver). |
| // For example, this could be a sequence id. |
| AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) |
| |
| // AddLink adds a link to the span. |
| AddLink(l Link) |
| |
| // String prints a string representation of a span. |
| String() string |
| } |
| |
| // NewSpan is a convenience function for creating a *Span out of a *span |
| func NewSpan(s SpanInterface) *Span { |
| return &Span{internal: s} |
| } |
| |
| // Span is a struct wrapper around the SpanInt interface, which allows correctly handling |
| // nil spans, while also allowing the SpanInterface implementation to be swapped out. |
| type Span struct { |
| internal SpanInterface |
| } |
| |
| // Internal returns the underlying implementation of the Span |
| func (s *Span) Internal() SpanInterface { |
| return s.internal |
| } |
| |
| // IsRecordingEvents returns true if events are being recorded for this span. |
| // Use this check to avoid computing expensive annotations when they will never |
| // be used. |
| func (s *Span) IsRecordingEvents() bool { |
| if s == nil { |
| return false |
| } |
| return s.internal.IsRecordingEvents() |
| } |
| |
| // End ends the span. |
| func (s *Span) End() { |
| if s == nil { |
| return |
| } |
| s.internal.End() |
| } |
| |
| // SpanContext returns the SpanContext of the span. |
| func (s *Span) SpanContext() SpanContext { |
| if s == nil { |
| return SpanContext{} |
| } |
| return s.internal.SpanContext() |
| } |
| |
| // SetName sets the name of the span, if it is recording events. |
| func (s *Span) SetName(name string) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.SetName(name) |
| } |
| |
| // SetStatus sets the status of the span, if it is recording events. |
| func (s *Span) SetStatus(status Status) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.SetStatus(status) |
| } |
| |
| // AddAttributes sets attributes in the span. |
| // |
| // Existing attributes whose keys appear in the attributes parameter are overwritten. |
| func (s *Span) AddAttributes(attributes ...Attribute) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.AddAttributes(attributes...) |
| } |
| |
| // Annotate adds an annotation with attributes. |
| // Attributes can be nil. |
| func (s *Span) Annotate(attributes []Attribute, str string) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.Annotate(attributes, str) |
| } |
| |
| // Annotatef adds an annotation with attributes. |
| func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.Annotatef(attributes, format, a...) |
| } |
| |
| // AddMessageSendEvent adds a message send event to the span. |
| // |
| // messageID is an identifier for the message, which is recommended to be |
| // unique in this span and the same between the send event and the receive |
| // event (this allows to identify a message between the sender and receiver). |
| // For example, this could be a sequence id. |
| func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize) |
| } |
| |
| // AddMessageReceiveEvent adds a message receive event to the span. |
| // |
| // messageID is an identifier for the message, which is recommended to be |
| // unique in this span and the same between the send event and the receive |
| // event (this allows to identify a message between the sender and receiver). |
| // For example, this could be a sequence id. |
| func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize) |
| } |
| |
| // AddLink adds a link to the span. |
| func (s *Span) AddLink(l Link) { |
| if !s.IsRecordingEvents() { |
| return |
| } |
| s.internal.AddLink(l) |
| } |
| |
| // String prints a string representation of a span. |
| func (s *Span) String() string { |
| if s == nil { |
| return "<nil>" |
| } |
| return s.internal.String() |
| } |