aboutsummaryrefslogblamecommitdiffstats
path: root/vendor/github.com/opentracing/opentracing-go/tracer.go
blob: 7bca1f73676d9bd25e2298a8cce425a3bfa5a42e (plain) (tree)
















































































































































































































































































































                                                                                     
package opentracing

import "time"

// Tracer is a simple, thin interface for Span creation and SpanContext
// propagation.
type Tracer interface {

    // Create, start, and return a new Span with the given `operationName` and
    // incorporate the given StartSpanOption `opts`. (Note that `opts` borrows
    // from the "functional options" pattern, per
    // http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis)
    //
    // A Span with no SpanReference options (e.g., opentracing.ChildOf() or
    // opentracing.FollowsFrom()) becomes the root of its own trace.
    //
    // Examples:
    //
    //     var tracer opentracing.Tracer = ...
    //
    //     // The root-span case:
    //     sp := tracer.StartSpan("GetFeed")
    //
    //     // The vanilla child span case:
    //     sp := tracer.StartSpan(
    //         "GetFeed",
    //         opentracing.ChildOf(parentSpan.Context()))
    //
    //     // All the bells and whistles:
    //     sp := tracer.StartSpan(
    //         "GetFeed",
    //         opentracing.ChildOf(parentSpan.Context()),
    //         opentracing.Tag{"user_agent", loggedReq.UserAgent},
    //         opentracing.StartTime(loggedReq.Timestamp),
    //     )
    //
    StartSpan(operationName string, opts ...StartSpanOption) Span

    // Inject() takes the `sm` SpanContext instance and injects it for
    // propagation within `carrier`. The actual type of `carrier` depends on
    // the value of `format`.
    //
    // OpenTracing defines a common set of `format` values (see BuiltinFormat),
    // and each has an expected carrier type.
    //
    // Other packages may declare their own `format` values, much like the keys
    // used by `context.Context` (see
    // https://godoc.org/golang.org/x/net/context#WithValue).
    //
    // Example usage (sans error handling):
    //
    //     carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
    //     err := tracer.Inject(
    //         span.Context(),
    //         opentracing.HTTPHeaders,
    //         carrier)
    //
    // NOTE: All opentracing.Tracer implementations MUST support all
    // BuiltinFormats.
    //
    // Implementations may return opentracing.ErrUnsupportedFormat if `format`
    // is not supported by (or not known by) the implementation.
    //
    // Implementations may return opentracing.ErrInvalidCarrier or any other
    // implementation-specific error if the format is supported but injection
    // fails anyway.
    //
    // See Tracer.Extract().
    Inject(sm SpanContext, format interface{}, carrier interface{}) error

    // Extract() returns a SpanContext instance given `format` and `carrier`.
    //
    // OpenTracing defines a common set of `format` values (see BuiltinFormat),
    // and each has an expected carrier type.
    //
    // Other packages may declare their own `format` values, much like the keys
    // used by `context.Context` (see
    // https://godoc.org/golang.org/x/net/context#WithValue).
    //
    // Example usage (with StartSpan):
    //
    //
    //     carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
    //     clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
    //
    //     // ... assuming the ultimate goal here is to resume the trace with a
    //     // server-side Span:
    //     var serverSpan opentracing.Span
    //     if err == nil {
    //         span = tracer.StartSpan(
    //             rpcMethodName, ext.RPCServerOption(clientContext))
    //     } else {
    //         span = tracer.StartSpan(rpcMethodName)
    //     }
    //
    //
    // NOTE: All opentracing.Tracer implementations MUST support all
    // BuiltinFormats.
    //
    // Return values:
    //  - A successful Extract returns a SpanContext instance and a nil error
    //  - If there was simply no SpanContext to extract in `carrier`, Extract()
    //    returns (nil, opentracing.ErrSpanContextNotFound)
    //  - If `format` is unsupported or unrecognized, Extract() returns (nil,
    //    opentracing.ErrUnsupportedFormat)
    //  - If there are more fundamental problems with the `carrier` object,
    //    Extract() may return opentracing.ErrInvalidCarrier,
    //    opentracing.ErrSpanContextCorrupted, or implementation-specific
    //    errors.
    //
    // See Tracer.Inject().
    Extract(format interface{}, carrier interface{}) (SpanContext, error)
}

// StartSpanOptions allows Tracer.StartSpan() callers and implementors a
// mechanism to override the start timestamp, specify Span References, and make
// a single Tag or multiple Tags available at Span start time.
//
// StartSpan() callers should look at the StartSpanOption interface and
// implementations available in this package.
//
// Tracer implementations can convert a slice of `StartSpanOption` instances
// into a `StartSpanOptions` struct like so:
//
//     func StartSpan(opName string, opts ...opentracing.StartSpanOption) {
//         sso := opentracing.StartSpanOptions{}
//         for _, o := range opts {
//             o.Apply(&sso)
//         }
//         ...
//     }
//
type StartSpanOptions struct {
    // Zero or more causal references to other Spans (via their SpanContext).
    // If empty, start a "root" Span (i.e., start a new trace).
    References []SpanReference

    // StartTime overrides the Span's start time, or implicitly becomes
    // time.Now() if StartTime.IsZero().
    StartTime time.Time

    // Tags may have zero or more entries; the restrictions on map values are
    // identical to those for Span.SetTag(). May be nil.
    //
    // If specified, the caller hands off ownership of Tags at
    // StartSpan() invocation time.
    Tags map[string]interface{}
}

// StartSpanOption instances (zero or more) may be passed to Tracer.StartSpan.
//
// StartSpanOption borrows from the "functional options" pattern, per
// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
type StartSpanOption interface {
    Apply(*StartSpanOptions)
}

// SpanReferenceType is an enum type describing different categories of
// relationships between two Spans. If Span-2 refers to Span-1, the
// SpanReferenceType describes Span-1 from Span-2's perspective. For example,
// ChildOfRef means that Span-1 created Span-2.
//
// NOTE: Span-1 and Span-2 do *not* necessarily depend on each other for
// completion; e.g., Span-2 may be part of a background job enqueued by Span-1,
// or Span-2 may be sitting in a distributed queue behind Span-1.
type SpanReferenceType int

const (
    // ChildOfRef refers to a parent Span that caused *and* somehow depends
    // upon the new child Span. Often (but not always), the parent Span cannot
    // finish until the child Span does.
    //
    // An timing diagram for a ChildOfRef that's blocked on the new Span:
    //
    //     [-Parent Span---------]
    //          [-Child Span----]
    //
    // See http://opentracing.io/spec/
    //
    // See opentracing.ChildOf()
    ChildOfRef SpanReferenceType = iota

    // FollowsFromRef refers to a parent Span that does not depend in any way
    // on the result of the new child Span. For instance, one might use
    // FollowsFromRefs to describe pipeline stages separated by queues,
    // or a fire-and-forget cache insert at the tail end of a web request.
    //
    // A FollowsFromRef Span is part of the same logical trace as the new Span:
    // i.e., the new Span is somehow caused by the work of its FollowsFromRef.
    //
    // All of the following could be valid timing diagrams for children that
    // "FollowFrom" a parent.
    //
    //     [-Parent Span-]  [-Child Span-]
    //
    //
    //     [-Parent Span--]
    //      [-Child Span-]
    //
    //
    //     [-Parent Span-]
    //                 [-Child Span-]
    //
    // See http://opentracing.io/spec/
    //
    // See opentracing.FollowsFrom()
    FollowsFromRef
)

// SpanReference is a StartSpanOption that pairs a SpanReferenceType and a
// referenced SpanContext. See the SpanReferenceType documentation for
// supported relationships.  If SpanReference is created with
// ReferencedContext==nil, it has no effect. Thus it allows for a more concise
// syntax for starting spans:
//
//     sc, _ := tracer.Extract(someFormat, someCarrier)
//     span := tracer.StartSpan("operation", opentracing.ChildOf(sc))
//
// The `ChildOf(sc)` option above will not panic if sc == nil, it will just
// not add the parent span reference to the options.
type SpanReference struct {
    Type              SpanReferenceType
    ReferencedContext SpanContext
}

// Apply satisfies the StartSpanOption interface.
func (r SpanReference) Apply(o *StartSpanOptions) {
    if r.ReferencedContext != nil {
        o.References = append(o.References, r)
    }
}

// ChildOf returns a StartSpanOption pointing to a dependent parent span.
// If sc == nil, the option has no effect.
//
// See ChildOfRef, SpanReference
func ChildOf(sc SpanContext) SpanReference {
    return SpanReference{
        Type:              ChildOfRef,
        ReferencedContext: sc,
    }
}

// FollowsFrom returns a StartSpanOption pointing to a parent Span that caused
// the child Span but does not directly depend on its result in any way.
// If sc == nil, the option has no effect.
//
// See FollowsFromRef, SpanReference
func FollowsFrom(sc SpanContext) SpanReference {
    return SpanReference{
        Type:              FollowsFromRef,
        ReferencedContext: sc,
    }
}

// StartTime is a StartSpanOption that sets an explicit start timestamp for the
// new Span.
type StartTime time.Time

// Apply satisfies the StartSpanOption interface.
func (t StartTime) Apply(o *StartSpanOptions) {
    o.StartTime = time.Time(t)
}

// Tags are a generic map from an arbitrary string key to an opaque value type.
// The underlying tracing system is responsible for interpreting and
// serializing the values.
type Tags map[string]interface{}

// Apply satisfies the StartSpanOption interface.
func (t Tags) Apply(o *StartSpanOptions) {
    if o.Tags == nil {
        o.Tags = make(map[string]interface{})
    }
    for k, v := range t {
        o.Tags[k] = v
    }
}

// Tag may be passed as a StartSpanOption to add a tag to new spans,
// or its Set method may be used to apply the tag to an existing Span,
// for example:
//
// tracer.StartSpan("opName", Tag{"Key", value})
//
//   or
//
// Tag{"key", value}.Set(span)
type Tag struct {
    Key   string
    Value interface{}
}

// Apply satisfies the StartSpanOption interface.
func (t Tag) Apply(o *StartSpanOptions) {
    if o.Tags == nil {
        o.Tags = make(map[string]interface{})
    }
    o.Tags[t.Key] = t.Value
}

// Set applies the tag to an existing Span.
func (t Tag) Set(s Span) {
    s.SetTag(t.Key, t.Value)
}