Marvin Preuss
1d4ae27878
All checks were successful
continuous-integration/drone/push Build is passing
266 lines
8.8 KiB
Go
266 lines
8.8 KiB
Go
// 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()
|
|
}
|