go.undefinedlabs.com/scopeagent@v0.4.2/instrumentation/process/context.go (about)

     1  package process
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"github.com/opentracing/opentracing-go"
     7  	"go.undefinedlabs.com/scopeagent/instrumentation"
     8  	"go.undefinedlabs.com/scopeagent/tracer"
     9  	"os"
    10  	"sync"
    11  )
    12  
    13  var (
    14  	processSpanContext opentracing.SpanContext
    15  	once               sync.Once
    16  )
    17  
    18  // Injects a context to the environment variables array
    19  func InjectFromContext(ctx context.Context, env *[]string) error {
    20  	if span := opentracing.SpanFromContext(ctx); span != nil {
    21  		return Inject(span.Context(), env)
    22  	}
    23  	return errors.New("there are no spans in the context")
    24  }
    25  
    26  // Injects the span context to the environment variables array
    27  func Inject(sm opentracing.SpanContext, env *[]string) error {
    28  	return instrumentation.Tracer().Inject(sm, tracer.EnvironmentVariableFormat, env)
    29  }
    30  
    31  // Extracts the span context from an environment variables array
    32  func Extract(env *[]string) (opentracing.SpanContext, error) {
    33  	return instrumentation.Tracer().Extract(tracer.EnvironmentVariableFormat, env)
    34  }
    35  
    36  // Gets the current span context from the environment variables, if available
    37  func SpanContext() opentracing.SpanContext {
    38  	once.Do(func() {
    39  		env := os.Environ()
    40  		if envCtx, err := Extract(&env); err == nil {
    41  			processSpanContext = envCtx
    42  		}
    43  	})
    44  	return processSpanContext
    45  }
    46  
    47  func StartSpan(opts ...opentracing.StartSpanOption) opentracing.Span {
    48  	if spanCtx := SpanContext(); spanCtx != nil {
    49  		opts = append(opts, opentracing.ChildOf(spanCtx))
    50  	}
    51  	return instrumentation.Tracer().StartSpan(getOperationNameFromArgs(os.Args), opts...)
    52  }
    53  
    54  func startSpanWithOperationName(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
    55  	if spanCtx := SpanContext(); spanCtx != nil {
    56  		opts = append(opts, opentracing.ChildOf(spanCtx))
    57  	}
    58  	return instrumentation.Tracer().StartSpan(operationName, opts...)
    59  }
    60  
    61  func StartSpanFromContext(ctx context.Context, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) {
    62  	if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil {
    63  		opts = append(opts, opentracing.ChildOf(parentSpan.Context()))
    64  	}
    65  	span := startSpanWithOperationName(operationName, opts...)
    66  	return span, opentracing.ContextWithSpan(ctx, span)
    67  }