aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/openzipkin/zipkin-go-opentracing/tracer.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/openzipkin/zipkin-go-opentracing/tracer.go')
-rw-r--r--vendor/github.com/openzipkin/zipkin-go-opentracing/tracer.go440
1 files changed, 0 insertions, 440 deletions
diff --git a/vendor/github.com/openzipkin/zipkin-go-opentracing/tracer.go b/vendor/github.com/openzipkin/zipkin-go-opentracing/tracer.go
deleted file mode 100644
index 5754d5fc5..000000000
--- a/vendor/github.com/openzipkin/zipkin-go-opentracing/tracer.go
+++ /dev/null
@@ -1,440 +0,0 @@
-package zipkintracer
-
-import (
- "errors"
- "time"
-
- opentracing "github.com/opentracing/opentracing-go"
- "github.com/opentracing/opentracing-go/ext"
-
- otobserver "github.com/opentracing-contrib/go-observer"
- "github.com/openzipkin/zipkin-go-opentracing/flag"
-)
-
-// ErrInvalidEndpoint will be thrown if hostPort parameter is corrupted or host
-// can't be resolved
-var ErrInvalidEndpoint = errors.New("Invalid Endpoint. Please check hostPort parameter")
-
-// Tracer extends the opentracing.Tracer interface with methods to
-// probe implementation state, for use by zipkintracer consumers.
-type Tracer interface {
- opentracing.Tracer
-
- // Options gets the Options used in New() or NewWithOptions().
- Options() TracerOptions
-}
-
-// TracerOptions allows creating a customized Tracer.
-type TracerOptions struct {
- // shouldSample is a function which is called when creating a new Span and
- // determines whether that Span is sampled. The randomized TraceID is supplied
- // to allow deterministic sampling decisions to be made across different nodes.
- shouldSample func(traceID uint64) bool
- // trimUnsampledSpans turns potentially expensive operations on unsampled
- // Spans into no-ops. More precisely, tags and log events are silently
- // discarded. If NewSpanEventListener is set, the callbacks will still fire.
- trimUnsampledSpans bool
- // recorder receives Spans which have been finished.
- recorder SpanRecorder
- // newSpanEventListener can be used to enhance the tracer by effectively
- // attaching external code to trace events. See NetTraceIntegrator for a
- // practical example, and event.go for the list of possible events.
- newSpanEventListener func() func(SpanEvent)
- // dropAllLogs turns log events on all Spans into no-ops.
- // If NewSpanEventListener is set, the callbacks will still fire.
- dropAllLogs bool
- // MaxLogsPerSpan limits the number of Logs in a span (if set to a nonzero
- // value). If a span has more logs than this value, logs are dropped as
- // necessary (and replaced with a log describing how many were dropped).
- //
- // About half of the MaxLogPerSpan logs kept are the oldest logs, and about
- // half are the newest logs.
- //
- // If NewSpanEventListener is set, the callbacks will still fire for all log
- // events. This value is ignored if DropAllLogs is true.
- maxLogsPerSpan int
- // debugAssertSingleGoroutine internally records the ID of the goroutine
- // creating each Span and verifies that no operation is carried out on
- // it on a different goroutine.
- // Provided strictly for development purposes.
- // Passing Spans between goroutine without proper synchronization often
- // results in use-after-Finish() errors. For a simple example, consider the
- // following pseudocode:
- //
- // func (s *Server) Handle(req http.Request) error {
- // sp := s.StartSpan("server")
- // defer sp.Finish()
- // wait := s.queueProcessing(opentracing.ContextWithSpan(context.Background(), sp), req)
- // select {
- // case resp := <-wait:
- // return resp.Error
- // case <-time.After(10*time.Second):
- // sp.LogEvent("timed out waiting for processing")
- // return ErrTimedOut
- // }
- // }
- //
- // This looks reasonable at first, but a request which spends more than ten
- // seconds in the queue is abandoned by the main goroutine and its trace
- // finished, leading to use-after-finish when the request is finally
- // processed. Note also that even joining on to a finished Span via
- // StartSpanWithOptions constitutes an illegal operation.
- //
- // Code bases which do not require (or decide they do not want) Spans to
- // be passed across goroutine boundaries can run with this flag enabled in
- // tests to increase their chances of spotting wrong-doers.
- debugAssertSingleGoroutine bool
- // debugAssertUseAfterFinish is provided strictly for development purposes.
- // When set, it attempts to exacerbate issues emanating from use of Spans
- // after calling Finish by running additional assertions.
- debugAssertUseAfterFinish bool
- // enableSpanPool enables the use of a pool, so that the tracer reuses spans
- // after Finish has been called on it. Adds a slight performance gain as it
- // reduces allocations. However, if you have any use-after-finish race
- // conditions the code may panic.
- enableSpanPool bool
- // logger ...
- logger Logger
- // clientServerSameSpan allows for Zipkin V1 style span per RPC. This places
- // both client end and server end of a RPC call into the same span.
- clientServerSameSpan bool
- // debugMode activates Zipkin's debug request allowing for all Spans originating
- // from this tracer to pass through and bypass sampling. Use with extreme care
- // as it might flood your system if you have many traces starting from the
- // service you are instrumenting.
- debugMode bool
- // traceID128Bit enables the generation of 128 bit traceIDs in case the tracer
- // needs to create a root span. By default regular 64 bit traceIDs are used.
- // Regardless of this setting, the library will propagate and support both
- // 64 and 128 bit incoming traces from upstream sources.
- traceID128Bit bool
-
- observer otobserver.Observer
-}
-
-// TracerOption allows for functional options.
-// See: http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
-type TracerOption func(opts *TracerOptions) error
-
-// WithSampler allows one to add a Sampler function
-func WithSampler(sampler Sampler) TracerOption {
- return func(opts *TracerOptions) error {
- opts.shouldSample = sampler
- return nil
- }
-}
-
-// TrimUnsampledSpans option
-func TrimUnsampledSpans(trim bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.trimUnsampledSpans = trim
- return nil
- }
-}
-
-// DropAllLogs option
-func DropAllLogs(dropAllLogs bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.dropAllLogs = dropAllLogs
- return nil
- }
-}
-
-// WithLogger option
-func WithLogger(logger Logger) TracerOption {
- return func(opts *TracerOptions) error {
- opts.logger = logger
- return nil
- }
-}
-
-// DebugAssertSingleGoroutine option
-func DebugAssertSingleGoroutine(val bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.debugAssertSingleGoroutine = val
- return nil
- }
-}
-
-// DebugAssertUseAfterFinish option
-func DebugAssertUseAfterFinish(val bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.debugAssertUseAfterFinish = val
- return nil
- }
-}
-
-// TraceID128Bit option
-func TraceID128Bit(val bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.traceID128Bit = val
- return nil
- }
-}
-
-// ClientServerSameSpan allows to place client-side and server-side annotations
-// for a RPC call in the same span (Zipkin V1 behavior) or different spans
-// (more in line with other tracing solutions). By default this Tracer
-// uses shared host spans (so client-side and server-side in the same span).
-// If using separate spans you might run into trouble with Zipkin V1 as clock
-// skew issues can't be remedied at Zipkin server side.
-func ClientServerSameSpan(val bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.clientServerSameSpan = val
- return nil
- }
-}
-
-// DebugMode allows to set the tracer to Zipkin debug mode
-func DebugMode(val bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.debugMode = val
- return nil
- }
-}
-
-// EnableSpanPool ...
-func EnableSpanPool(val bool) TracerOption {
- return func(opts *TracerOptions) error {
- opts.enableSpanPool = val
- return nil
- }
-}
-
-// NewSpanEventListener option
-func NewSpanEventListener(f func() func(SpanEvent)) TracerOption {
- return func(opts *TracerOptions) error {
- opts.newSpanEventListener = f
- return nil
- }
-}
-
-// WithMaxLogsPerSpan option
-func WithMaxLogsPerSpan(limit int) TracerOption {
- return func(opts *TracerOptions) error {
- if limit < 5 || limit > 10000 {
- return errors.New("invalid MaxLogsPerSpan limit. Should be between 5 and 10000")
- }
- opts.maxLogsPerSpan = limit
- return nil
- }
-}
-
-// NewTracer creates a new OpenTracing compatible Zipkin Tracer.
-func NewTracer(recorder SpanRecorder, options ...TracerOption) (opentracing.Tracer, error) {
- opts := &TracerOptions{
- recorder: recorder,
- shouldSample: alwaysSample,
- trimUnsampledSpans: false,
- newSpanEventListener: func() func(SpanEvent) { return nil },
- logger: &nopLogger{},
- debugAssertSingleGoroutine: false,
- debugAssertUseAfterFinish: false,
- clientServerSameSpan: true,
- debugMode: false,
- traceID128Bit: false,
- maxLogsPerSpan: 10000,
- observer: nil,
- }
- for _, o := range options {
- err := o(opts)
- if err != nil {
- return nil, err
- }
- }
- rval := &tracerImpl{options: *opts}
- rval.textPropagator = &textMapPropagator{rval}
- rval.binaryPropagator = &binaryPropagator{rval}
- rval.accessorPropagator = &accessorPropagator{rval}
- return rval, nil
-}
-
-// Implements the `Tracer` interface.
-type tracerImpl struct {
- options TracerOptions
- textPropagator *textMapPropagator
- binaryPropagator *binaryPropagator
- accessorPropagator *accessorPropagator
-}
-
-func (t *tracerImpl) StartSpan(
- operationName string,
- opts ...opentracing.StartSpanOption,
-) opentracing.Span {
- sso := opentracing.StartSpanOptions{}
- for _, o := range opts {
- o.Apply(&sso)
- }
- return t.startSpanWithOptions(operationName, sso)
-}
-
-func (t *tracerImpl) getSpan() *spanImpl {
- if t.options.enableSpanPool {
- sp := spanPool.Get().(*spanImpl)
- sp.reset()
- return sp
- }
- return &spanImpl{}
-}
-
-func (t *tracerImpl) startSpanWithOptions(
- operationName string,
- opts opentracing.StartSpanOptions,
-) opentracing.Span {
- // Start time.
- startTime := opts.StartTime
- if startTime.IsZero() {
- startTime = time.Now()
- }
-
- // Tags.
- tags := opts.Tags
-
- // Build the new span. This is the only allocation: We'll return this as
- // an opentracing.Span.
- sp := t.getSpan()
-
- if t.options.observer != nil {
- sp.observer, _ = t.options.observer.OnStartSpan(sp, operationName, opts)
- }
-
- // Look for a parent in the list of References.
- //
- // TODO: would be nice if basictracer did something with all
- // References, not just the first one.
-ReferencesLoop:
- for _, ref := range opts.References {
- switch ref.Type {
- case opentracing.ChildOfRef:
- refCtx := ref.ReferencedContext.(SpanContext)
- sp.raw.Context.TraceID = refCtx.TraceID
- sp.raw.Context.ParentSpanID = &refCtx.SpanID
- sp.raw.Context.Sampled = refCtx.Sampled
- sp.raw.Context.Flags = refCtx.Flags
- sp.raw.Context.Flags &^= flag.IsRoot // unset IsRoot flag if needed
-
- if t.options.clientServerSameSpan &&
- tags[string(ext.SpanKind)] == ext.SpanKindRPCServer.Value {
- sp.raw.Context.SpanID = refCtx.SpanID
- sp.raw.Context.ParentSpanID = refCtx.ParentSpanID
- sp.raw.Context.Owner = false
- } else {
- sp.raw.Context.SpanID = randomID()
- sp.raw.Context.ParentSpanID = &refCtx.SpanID
- sp.raw.Context.Owner = true
- }
-
- if l := len(refCtx.Baggage); l > 0 {
- sp.raw.Context.Baggage = make(map[string]string, l)
- for k, v := range refCtx.Baggage {
- sp.raw.Context.Baggage[k] = v
- }
- }
- break ReferencesLoop
- case opentracing.FollowsFromRef:
- refCtx := ref.ReferencedContext.(SpanContext)
- sp.raw.Context.TraceID = refCtx.TraceID
- sp.raw.Context.ParentSpanID = &refCtx.SpanID
- sp.raw.Context.Sampled = refCtx.Sampled
- sp.raw.Context.Flags = refCtx.Flags
- sp.raw.Context.Flags &^= flag.IsRoot // unset IsRoot flag if needed
-
- sp.raw.Context.SpanID = randomID()
- sp.raw.Context.ParentSpanID = &refCtx.SpanID
- sp.raw.Context.Owner = true
-
- if l := len(refCtx.Baggage); l > 0 {
- sp.raw.Context.Baggage = make(map[string]string, l)
- for k, v := range refCtx.Baggage {
- sp.raw.Context.Baggage[k] = v
- }
- }
- break ReferencesLoop
- }
- }
- if sp.raw.Context.TraceID.Empty() {
- // No parent Span found; allocate new trace and span ids and determine
- // the Sampled status.
- if t.options.traceID128Bit {
- sp.raw.Context.TraceID.High = randomID()
- }
- sp.raw.Context.TraceID.Low, sp.raw.Context.SpanID = randomID2()
- sp.raw.Context.Sampled = t.options.shouldSample(sp.raw.Context.TraceID.Low)
- sp.raw.Context.Flags = flag.IsRoot
- sp.raw.Context.Owner = true
- }
- if t.options.debugMode {
- sp.raw.Context.Flags |= flag.Debug
- }
- return t.startSpanInternal(
- sp,
- operationName,
- startTime,
- tags,
- )
-}
-
-func (t *tracerImpl) startSpanInternal(
- sp *spanImpl,
- operationName string,
- startTime time.Time,
- tags opentracing.Tags,
-) opentracing.Span {
- sp.tracer = t
- if t.options.newSpanEventListener != nil {
- sp.event = t.options.newSpanEventListener()
- }
- sp.raw.Operation = operationName
- sp.raw.Start = startTime
- sp.raw.Duration = -1
- sp.raw.Tags = tags
-
- if t.options.debugAssertSingleGoroutine {
- sp.SetTag(debugGoroutineIDTag, curGoroutineID())
- }
- defer sp.onCreate(operationName)
- return sp
-}
-
-type delegatorType struct{}
-
-// Delegator is the format to use for DelegatingCarrier.
-var Delegator delegatorType
-
-func (t *tracerImpl) Inject(sc opentracing.SpanContext, format interface{}, carrier interface{}) error {
- switch format {
- case opentracing.TextMap, opentracing.HTTPHeaders:
- return t.textPropagator.Inject(sc, carrier)
- case opentracing.Binary:
- return t.binaryPropagator.Inject(sc, carrier)
- }
- if _, ok := format.(delegatorType); ok {
- return t.accessorPropagator.Inject(sc, carrier)
- }
- return opentracing.ErrUnsupportedFormat
-}
-
-func (t *tracerImpl) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
- switch format {
- case opentracing.TextMap, opentracing.HTTPHeaders:
- return t.textPropagator.Extract(carrier)
- case opentracing.Binary:
- return t.binaryPropagator.Extract(carrier)
- }
- if _, ok := format.(delegatorType); ok {
- return t.accessorPropagator.Extract(carrier)
- }
- return nil, opentracing.ErrUnsupportedFormat
-}
-
-func (t *tracerImpl) Options() TracerOptions {
- return t.options
-}
-
-// WithObserver assigns an initialized observer to opts.observer
-func WithObserver(observer otobserver.Observer) TracerOption {
- return func(opts *TracerOptions) error {
- opts.observer = observer
- return nil
- }
-}