github.com/m3db/m3@v1.5.0/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 }