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  }