github.com/blend/go-sdk@v1.20220411.3/tracing/tracing.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package tracing 9 10 import ( 11 "context" 12 "fmt" 13 14 opentracing "github.com/opentracing/opentracing-go" 15 16 "github.com/blend/go-sdk/ex" 17 ) 18 19 // StartSpanFromContext creates a new span from a given context. 20 // It is required because opentracing relies on global state. 21 func StartSpanFromContext(ctx context.Context, tracer opentracing.Tracer, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) { 22 if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil { 23 opts = append(opts, opentracing.ChildOf(parentSpan.Context())) 24 } 25 span := tracer.StartSpan(operationName, opts...) 26 ctx = WithTraceAnnotations(ctx, span.Context()) 27 return span, opentracing.ContextWithSpan(ctx, span) 28 } 29 30 // GetTracingSpanFromContext returns a tracing span from a given context. 31 func GetTracingSpanFromContext(ctx context.Context, key interface{}) opentracing.Span { 32 if typed, ok := ctx.Value(key).(opentracing.Span); ok { 33 return typed 34 } 35 return nil 36 } 37 38 // Background returns a new `context.Background()` 39 // with the parent span from a given context. 40 // 41 // It is useful if you want to kick out goroutines but 42 // maintain tracing data. 43 func Background(ctx context.Context) context.Context { 44 output := context.Background() 45 if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil { 46 return opentracing.ContextWithSpan(output, parentSpan) 47 } 48 return output 49 } 50 51 // SpanError injects error metadata into a span. 52 func SpanError(span opentracing.Span, err error) { 53 if err != nil { 54 if typed := ex.As(err); typed != nil { 55 span.SetTag(TagKeyError, typed.Class) 56 span.SetTag(TagKeyErrorType, typed.Class) 57 span.SetTag(TagKeyErrorMessage, typed.Message) 58 span.SetTag(TagKeyErrorStack, typed.StackTrace.String()) 59 span.SetTag(TagKeyErrorDetails, fmt.Sprintf("%+v", err)) 60 } else { 61 span.SetTag(TagKeyError, fmt.Sprintf("%v", err)) 62 } 63 } 64 } 65 66 // TagMeasured returns an opentracing tag to indicate the span should be measured. 67 func TagMeasured() opentracing.Tag { 68 return opentracing.Tag{Key: TagKeyMeasured, Value: 1} 69 }