aboutsummaryrefslogtreecommitdiff
path: root/vendor/go.opencensus.io/trace/trace.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.opencensus.io/trace/trace.go')
-rw-r--r--vendor/go.opencensus.io/trace/trace.go511
1 files changed, 0 insertions, 511 deletions
diff --git a/vendor/go.opencensus.io/trace/trace.go b/vendor/go.opencensus.io/trace/trace.go
deleted file mode 100644
index 887e90b..0000000
--- a/vendor/go.opencensus.io/trace/trace.go
+++ /dev/null
@@ -1,511 +0,0 @@
-// Copyright 2017, 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"
- crand "crypto/rand"
- "encoding/binary"
- "fmt"
- "math/rand"
- "sync"
- "sync/atomic"
- "time"
-
- "go.opencensus.io/internal"
-)
-
-// Span 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 Span struct {
- // data contains information recorded about the span.
- //
- // It will be non-nil if we are exporting the span or recording events for it.
- // Otherwise, data is nil, and the Span is simply a carrier for the
- // SpanContext, so that the trace ID is propagated.
- data *SpanData
- mu sync.Mutex // protects the contents of *data (but not the pointer value.)
- spanContext SpanContext
- // spanStore is the spanStore this span belongs to, if any, otherwise it is nil.
- *spanStore
- endOnce sync.Once
-
- executionTracerTaskEnd func() // ends the execution tracer span
-}
-
-// 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.data != nil
-}
-
-// TraceOptions contains options associated with a trace span.
-type TraceOptions uint32
-
-// IsSampled returns true if the span will be exported.
-func (sc SpanContext) IsSampled() bool {
- return sc.TraceOptions.IsSampled()
-}
-
-// setIsSampled sets the TraceOptions bit that determines whether the span will be exported.
-func (sc *SpanContext) setIsSampled(sampled bool) {
- if sampled {
- sc.TraceOptions |= 1
- } else {
- sc.TraceOptions &= ^TraceOptions(1)
- }
-}
-
-// IsSampled returns true if the span will be exported.
-func (t TraceOptions) IsSampled() bool {
- return t&1 == 1
-}
-
-// SpanContext contains the state that must propagate across process boundaries.
-//
-// SpanContext is not an implementation of context.Context.
-// TODO: add reference to external Census docs for SpanContext.
-type SpanContext struct {
- TraceID TraceID
- SpanID SpanID
- TraceOptions TraceOptions
-}
-
-type contextKey struct{}
-
-// FromContext returns the Span stored in a context, or nil if there isn't one.
-func FromContext(ctx context.Context) *Span {
- s, _ := ctx.Value(contextKey{}).(*Span)
- return s
-}
-
-// NewContext returns a new context with the given Span attached.
-func NewContext(parent context.Context, s *Span) context.Context {
- return context.WithValue(parent, contextKey{}, s)
-}
-
-// All available span kinds. Span kind must be either one of these values.
-const (
- SpanKindUnspecified = iota
- SpanKindServer
- SpanKindClient
-)
-
-// StartOptions contains options concerning how a span is started.
-type StartOptions struct {
- // Sampler to consult for this Span. If provided, it is always consulted.
- //
- // If not provided, then the behavior differs based on whether
- // the parent of this Span is remote, local, or there is no parent.
- // In the case of a remote parent or no parent, the
- // default sampler (see Config) will be consulted. Otherwise,
- // when there is a non-remote parent, no new sampling decision will be made:
- // we will preserve the sampling of the parent.
- Sampler Sampler
-
- // SpanKind represents the kind of a span. If none is set,
- // SpanKindUnspecified is used.
- SpanKind int
-}
-
-// StartOption apply changes to StartOptions.
-type StartOption func(*StartOptions)
-
-// WithSpanKind makes new spans to be created with the given kind.
-func WithSpanKind(spanKind int) StartOption {
- return func(o *StartOptions) {
- o.SpanKind = spanKind
- }
-}
-
-// WithSampler makes new spans to be be created with a custom sampler.
-// Otherwise, the global sampler is used.
-func WithSampler(sampler Sampler) StartOption {
- return func(o *StartOptions) {
- o.Sampler = sampler
- }
-}
-
-// 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) {
- var opts StartOptions
- var parent SpanContext
- if p := FromContext(ctx); p != nil {
- parent = p.spanContext
- }
- for _, op := range o {
- op(&opts)
- }
- span := startSpanInternal(name, parent != SpanContext{}, parent, false, opts)
-
- ctx, end := startExecutionTracerTask(ctx, name)
- span.executionTracerTaskEnd = end
- return NewContext(ctx, span), 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.
-func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) {
- var opts StartOptions
- for _, op := range o {
- op(&opts)
- }
- span := startSpanInternal(name, parent != SpanContext{}, parent, true, opts)
- ctx, end := startExecutionTracerTask(ctx, name)
- span.executionTracerTaskEnd = end
- return NewContext(ctx, span), span
-}
-
-func startSpanInternal(name string, hasParent bool, parent SpanContext, remoteParent bool, o StartOptions) *Span {
- span := &Span{}
- span.spanContext = parent
-
- cfg := config.Load().(*Config)
-
- if !hasParent {
- span.spanContext.TraceID = cfg.IDGenerator.NewTraceID()
- }
- span.spanContext.SpanID = cfg.IDGenerator.NewSpanID()
- sampler := cfg.DefaultSampler
-
- if !hasParent || remoteParent || o.Sampler != nil {
- // If this span is the child of a local span and no Sampler is set in the
- // options, keep the parent's TraceOptions.
- //
- // Otherwise, consult the Sampler in the options if it is non-nil, otherwise
- // the default sampler.
- if o.Sampler != nil {
- sampler = o.Sampler
- }
- span.spanContext.setIsSampled(sampler(SamplingParameters{
- ParentContext: parent,
- TraceID: span.spanContext.TraceID,
- SpanID: span.spanContext.SpanID,
- Name: name,
- HasRemoteParent: remoteParent}).Sample)
- }
-
- if !internal.LocalSpanStoreEnabled && !span.spanContext.IsSampled() {
- return span
- }
-
- span.data = &SpanData{
- SpanContext: span.spanContext,
- StartTime: time.Now(),
- SpanKind: o.SpanKind,
- Name: name,
- HasRemoteParent: remoteParent,
- }
- if hasParent {
- span.data.ParentSpanID = parent.SpanID
- }
- if internal.LocalSpanStoreEnabled {
- var ss *spanStore
- ss = spanStoreForNameCreateIfNew(name)
- if ss != nil {
- span.spanStore = ss
- ss.add(span)
- }
- }
-
- return span
-}
-
-// End ends the span.
-func (s *Span) End() {
- if !s.IsRecordingEvents() {
- return
- }
- s.endOnce.Do(func() {
- if s.executionTracerTaskEnd != nil {
- s.executionTracerTaskEnd()
- }
- exp, _ := exporters.Load().(exportersMap)
- mustExport := s.spanContext.IsSampled() && len(exp) > 0
- if s.spanStore != nil || mustExport {
- sd := s.makeSpanData()
- sd.EndTime = internal.MonotonicEndTime(sd.StartTime)
- if s.spanStore != nil {
- s.spanStore.finished(s, sd)
- }
- if mustExport {
- for e := range exp {
- e.ExportSpan(sd)
- }
- }
- }
- })
-}
-
-// makeSpanData produces a SpanData representing the current state of the Span.
-// It requires that s.data is non-nil.
-func (s *Span) makeSpanData() *SpanData {
- var sd SpanData
- s.mu.Lock()
- sd = *s.data
- if s.data.Attributes != nil {
- sd.Attributes = make(map[string]interface{})
- for k, v := range s.data.Attributes {
- sd.Attributes[k] = v
- }
- }
- s.mu.Unlock()
- return &sd
-}
-
-// SpanContext returns the SpanContext of the span.
-func (s *Span) SpanContext() SpanContext {
- if s == nil {
- return SpanContext{}
- }
- return s.spanContext
-}
-
-// SetName sets the name of the span, if it is recording events.
-func (s *Span) SetName(name string) {
- if !s.IsRecordingEvents() {
- return
- }
- s.mu.Lock()
- s.data.Name = name
- s.mu.Unlock()
-}
-
-// SetStatus sets the status of the span, if it is recording events.
-func (s *Span) SetStatus(status Status) {
- if !s.IsRecordingEvents() {
- return
- }
- s.mu.Lock()
- s.data.Status = status
- s.mu.Unlock()
-}
-
-// 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.mu.Lock()
- if s.data.Attributes == nil {
- s.data.Attributes = make(map[string]interface{})
- }
- copyAttributes(s.data.Attributes, attributes)
- s.mu.Unlock()
-}
-
-// copyAttributes copies a slice of Attributes into a map.
-func copyAttributes(m map[string]interface{}, attributes []Attribute) {
- for _, a := range attributes {
- m[a.key] = a.value
- }
-}
-
-func (s *Span) lazyPrintfInternal(attributes []Attribute, format string, a ...interface{}) {
- now := time.Now()
- msg := fmt.Sprintf(format, a...)
- var m map[string]interface{}
- s.mu.Lock()
- if len(attributes) != 0 {
- m = make(map[string]interface{})
- copyAttributes(m, attributes)
- }
- s.data.Annotations = append(s.data.Annotations, Annotation{
- Time: now,
- Message: msg,
- Attributes: m,
- })
- s.mu.Unlock()
-}
-
-func (s *Span) printStringInternal(attributes []Attribute, str string) {
- now := time.Now()
- var a map[string]interface{}
- s.mu.Lock()
- if len(attributes) != 0 {
- a = make(map[string]interface{})
- copyAttributes(a, attributes)
- }
- s.data.Annotations = append(s.data.Annotations, Annotation{
- Time: now,
- Message: str,
- Attributes: a,
- })
- s.mu.Unlock()
-}
-
-// Annotate adds an annotation with attributes.
-// Attributes can be nil.
-func (s *Span) Annotate(attributes []Attribute, str string) {
- if !s.IsRecordingEvents() {
- return
- }
- s.printStringInternal(attributes, str)
-}
-
-// Annotatef adds an annotation with attributes.
-func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) {
- if !s.IsRecordingEvents() {
- return
- }
- s.lazyPrintfInternal(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
- }
- now := time.Now()
- s.mu.Lock()
- s.data.MessageEvents = append(s.data.MessageEvents, MessageEvent{
- Time: now,
- EventType: MessageEventTypeSent,
- MessageID: messageID,
- UncompressedByteSize: uncompressedByteSize,
- CompressedByteSize: compressedByteSize,
- })
- s.mu.Unlock()
-}
-
-// 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
- }
- now := time.Now()
- s.mu.Lock()
- s.data.MessageEvents = append(s.data.MessageEvents, MessageEvent{
- Time: now,
- EventType: MessageEventTypeRecv,
- MessageID: messageID,
- UncompressedByteSize: uncompressedByteSize,
- CompressedByteSize: compressedByteSize,
- })
- s.mu.Unlock()
-}
-
-// AddLink adds a link to the span.
-func (s *Span) AddLink(l Link) {
- if !s.IsRecordingEvents() {
- return
- }
- s.mu.Lock()
- s.data.Links = append(s.data.Links, l)
- s.mu.Unlock()
-}
-
-func (s *Span) String() string {
- if s == nil {
- return "<nil>"
- }
- if s.data == nil {
- return fmt.Sprintf("span %s", s.spanContext.SpanID)
- }
- s.mu.Lock()
- str := fmt.Sprintf("span %s %q", s.spanContext.SpanID, s.data.Name)
- s.mu.Unlock()
- return str
-}
-
-var config atomic.Value // access atomically
-
-func init() {
- gen := &defaultIDGenerator{}
- // initialize traceID and spanID generators.
- var rngSeed int64
- for _, p := range []interface{}{
- &rngSeed, &gen.traceIDAdd, &gen.nextSpanID, &gen.spanIDInc,
- } {
- binary.Read(crand.Reader, binary.LittleEndian, p)
- }
- gen.traceIDRand = rand.New(rand.NewSource(rngSeed))
- gen.spanIDInc |= 1
-
- config.Store(&Config{
- DefaultSampler: ProbabilitySampler(defaultSamplingProbability),
- IDGenerator: gen,
- })
-}
-
-type defaultIDGenerator struct {
- sync.Mutex
-
- // Please keep these as the first fields
- // so that these 8 byte fields will be aligned on addresses
- // divisible by 8, on both 32-bit and 64-bit machines when
- // performing atomic increments and accesses.
- // See:
- // * https://github.com/census-instrumentation/opencensus-go/issues/587
- // * https://github.com/census-instrumentation/opencensus-go/issues/865
- // * https://golang.org/pkg/sync/atomic/#pkg-note-BUG
- nextSpanID uint64
- spanIDInc uint64
-
- traceIDAdd [2]uint64
- traceIDRand *rand.Rand
-}
-
-// NewSpanID returns a non-zero span ID from a randomly-chosen sequence.
-func (gen *defaultIDGenerator) NewSpanID() [8]byte {
- var id uint64
- for id == 0 {
- id = atomic.AddUint64(&gen.nextSpanID, gen.spanIDInc)
- }
- var sid [8]byte
- binary.LittleEndian.PutUint64(sid[:], id)
- return sid
-}
-
-// NewTraceID returns a non-zero trace ID from a randomly-chosen sequence.
-// mu should be held while this function is called.
-func (gen *defaultIDGenerator) NewTraceID() [16]byte {
- var tid [16]byte
- // Construct the trace ID from two outputs of traceIDRand, with a constant
- // added to each half for additional entropy.
- gen.Lock()
- binary.LittleEndian.PutUint64(tid[0:8], gen.traceIDRand.Uint64()+gen.traceIDAdd[0])
- binary.LittleEndian.PutUint64(tid[8:16], gen.traceIDRand.Uint64()+gen.traceIDAdd[1])
- gen.Unlock()
- return tid
-}