github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/x/opentracing/context.go (about)

     1  // Copyright (c) 2019 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package opentracing
    22  
    23  import (
    24  	"context"
    25  	"fmt"
    26  	"time"
    27  
    28  	"github.com/opentracing/opentracing-go"
    29  	"github.com/opentracing/opentracing-go/log"
    30  )
    31  
    32  // alias GlobalTracer() so we can mock out the tracer without impacting tests outside the package
    33  var getGlobalTracer = opentracing.GlobalTracer
    34  
    35  // SpanFromContextOrNoop is the same as opentracing.SpanFromContext,
    36  // but instead of returning nil,
    37  // it returns a NoopTracer span if ctx doesn't already have an associated span.
    38  // Use this over opentracing.StartSpanFromContext if you need access to the
    39  // current span, (e.g. if you don't want to start a child span).
    40  //
    41  // NB: if there is no span in the context, the span returned by this function
    42  // is a noop, and won't be attached to the context; if you
    43  // want a proper span, either start one and pass it in, or start one
    44  // in your function.
    45  func SpanFromContextOrNoop(ctx context.Context) opentracing.Span {
    46  	sp := opentracing.SpanFromContext(ctx)
    47  	if sp != nil {
    48  		return sp
    49  	}
    50  
    51  	return opentracing.NoopTracer{}.StartSpan("")
    52  }
    53  
    54  // StartSpanFromContext is the same as opentracing.StartSpanFromContext, but instead of always using the global tracer,
    55  // it attempts to use the parent span's tracer if it's available. This behavior is (arguably) more flexible--it allows
    56  // a locally set tracer to be used when needed (as in tests)--while being equivalent to the original in most contexts.
    57  // See https://github.com/opentracing/opentracing-go/issues/149 for more discussion.
    58  func StartSpanFromContext(ctx context.Context, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) {
    59  	var tracer opentracing.Tracer
    60  	if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil {
    61  		opts = append(opts, opentracing.ChildOf(parentSpan.Context()))
    62  		tracer = parentSpan.Tracer()
    63  	} else {
    64  		tracer = getGlobalTracer()
    65  	}
    66  
    67  	span := tracer.StartSpan(operationName, opts...)
    68  
    69  	return span, opentracing.ContextWithSpan(ctx, span)
    70  }
    71  
    72  // Time is a log.Field for time.Time values. It translates to RFC3339 formatted time strings.
    73  // (e.g. 2018-04-15T13:47:26+00:00)
    74  func Time(key string, t time.Time) log.Field {
    75  	return log.String(key, t.Format(time.RFC3339))
    76  }
    77  
    78  // Duration is a log.Field for Duration values. It translates to the standard Go duration format (Duration.String()).
    79  func Duration(key string, t time.Duration) log.Field {
    80  	return log.String(key, fmt.Sprint(t))
    81  }