gitlab.com/gitlab-org/labkit@v1.21.0/tracing/env_injector.go (about)

     1  package tracing
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"sort"
     8  
     9  	opentracing "github.com/opentracing/opentracing-go"
    10  	"gitlab.com/gitlab-org/labkit/correlation"
    11  	logkit "gitlab.com/gitlab-org/labkit/log"
    12  )
    13  
    14  // envCorrelationIDKey is used to pass the current correlation-id over to the child process.
    15  const envCorrelationIDKey = "CORRELATION_ID"
    16  
    17  // EnvInjector will inject tracing information into an environment in preparation for
    18  // spawning a child process. This includes trace and span identifiers, as well
    19  // as the GITLAB_TRACING configuration. Will gracefully degrade if tracing is
    20  // not configured, or an active span is not currently available.
    21  type EnvInjector func(ctx context.Context, env []string) []string
    22  
    23  // NewEnvInjector will create a new environment injector.
    24  func NewEnvInjector(opts ...EnvInjectorOption) EnvInjector {
    25  	/* config not yet used */ applyEnvInjectorOptions(opts)
    26  
    27  	return func(ctx context.Context, env []string) []string {
    28  		envMap := map[string]string{}
    29  
    30  		// Pass the Correlation-ID through the environment if set
    31  		correlationID := correlation.ExtractFromContext(ctx)
    32  		if correlationID != "" {
    33  			envMap[envCorrelationIDKey] = correlationID
    34  		}
    35  
    36  		// Also include the GITLAB_TRACING configuration so that
    37  		// the child process knows how to configure itself
    38  		v, ok := os.LookupEnv(tracingEnvKey)
    39  		if ok {
    40  			envMap[tracingEnvKey] = v
    41  		}
    42  
    43  		span := opentracing.SpanFromContext(ctx)
    44  		if span == nil {
    45  			// If no active span, short circuit
    46  			return appendMapToEnv(env, envMap)
    47  		}
    48  
    49  		carrier := opentracing.TextMapCarrier(envMap)
    50  		err := span.Tracer().Inject(span.Context(), opentracing.TextMap, carrier)
    51  
    52  		if err != nil {
    53  			logkit.ContextLogger(ctx).WithError(err).Error("tracing span injection failed")
    54  		}
    55  
    56  		return appendMapToEnv(env, envMap)
    57  	}
    58  }
    59  
    60  // appendMapToEnv takes a map of key,value pairs and appends it to an
    61  // array of environment variable pairs in `K=V` string pairs.
    62  func appendMapToEnv(env []string, envMap map[string]string) []string {
    63  	additionalItems := []string{}
    64  	for k, v := range envMap {
    65  		additionalItems = append(additionalItems, fmt.Sprintf("%s=%s", k, v))
    66  	}
    67  
    68  	sort.Strings(additionalItems)
    69  	return append(env, additionalItems...)
    70  }