github.com/blend/go-sdk@v1.20240719.1/tracing/tracing.go (about) 1 /* 2 3 Copyright (c) 2024 - 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) opentracing.Span { 32 return opentracing.SpanFromContext(ctx) 33 } 34 35 // Background returns a new `context.Background()` 36 // with the parent span from a given context. 37 // 38 // It is useful if you want to kick out goroutines but 39 // maintain tracing data. 40 func Background(ctx context.Context) context.Context { 41 output := context.Background() 42 if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil { 43 return opentracing.ContextWithSpan(output, parentSpan) 44 } 45 return output 46 } 47 48 // SpanError injects error metadata into a span. 49 func SpanError(span opentracing.Span, err error) { 50 if err != nil { 51 if typed := ex.As(err); typed != nil { 52 span.SetTag(TagKeyError, typed.Class) 53 span.SetTag(TagKeyErrorType, typed.Class) 54 span.SetTag(TagKeyErrorMessage, typed.Message) 55 span.SetTag(TagKeyErrorStack, typed.StackTrace.String()) 56 span.SetTag(TagKeyErrorDetails, fmt.Sprintf("%+v", err)) 57 } else { 58 span.SetTag(TagKeyError, fmt.Sprintf("%v", err)) 59 } 60 } 61 } 62 63 // TagMeasured returns an opentracing tag to indicate the span should be measured. 64 func TagMeasured() opentracing.Tag { 65 return opentracing.Tag{Key: TagKeyMeasured, Value: 1} 66 }