github.com/thanos-io/thanos@v0.32.5/pkg/tracing/lightstep/lightstep.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package lightstep
     5  
     6  import (
     7  	"context"
     8  	"io"
     9  	"os"
    10  	"strings"
    11  
    12  	"github.com/lightstep/lightstep-tracer-go"
    13  	"github.com/opentracing/opentracing-go"
    14  	"gopkg.in/yaml.v2"
    15  )
    16  
    17  // Config - YAML configuration.
    18  type Config struct {
    19  	// AccessToken is the unique API key for your LightStep project. It is
    20  	// available on your account page at https://app.lightstep.com/account.
    21  	AccessToken string `yaml:"access_token"`
    22  
    23  	// Collector is the host, port, and plaintext option to use
    24  	// for the collector.
    25  	Collector lightstep.Endpoint `yaml:"collector"`
    26  
    27  	// Tags is a string comma-delimited of key value pairs that holds metadata that will be sent to lightstep
    28  	Tags string `yaml:"tags"`
    29  }
    30  
    31  // Tracer wraps the Lightstep tracer and the context.
    32  type Tracer struct {
    33  	lightstep.Tracer
    34  	ctx context.Context
    35  }
    36  
    37  // Close synchronously flushes the Lightstep tracer, then terminates it.
    38  func (t *Tracer) Close() error {
    39  	t.Tracer.Close(t.ctx)
    40  
    41  	return nil
    42  }
    43  
    44  // NewTracer creates a Tracer with the options present in the YAML config.
    45  func NewTracer(ctx context.Context, yamlConfig []byte) (opentracing.Tracer, io.Closer, error) {
    46  	config := Config{}
    47  	if err := yaml.Unmarshal(yamlConfig, &config); err != nil {
    48  		return nil, nil, err
    49  	}
    50  
    51  	var tags opentracing.Tags
    52  	if config.Tags != "" {
    53  		tags = parseTags(config.Tags)
    54  	}
    55  
    56  	options := lightstep.Options{
    57  		AccessToken: config.AccessToken,
    58  		Collector:   config.Collector,
    59  		Tags:        tags,
    60  	}
    61  	lighstepTracer, err := lightstep.CreateTracer(options)
    62  	if err != nil {
    63  		return nil, nil, err
    64  	}
    65  
    66  	t := &Tracer{
    67  		lighstepTracer,
    68  		ctx,
    69  	}
    70  	return t, t, nil
    71  }
    72  
    73  // parseTags parses the given string into a map of strings to empty interface.
    74  // Spec for this value:
    75  // - comma separated list of key=value
    76  // - value can be specified using the notation ${envVar:defaultValue}, where `envVar`
    77  // is an environment variable and `defaultValue` is the value to use in case the env var is not set.
    78  func parseTags(sTags string) opentracing.Tags {
    79  	pairs := strings.Split(sTags, ",")
    80  	tags := make(opentracing.Tags)
    81  	for _, p := range pairs {
    82  		kv := strings.SplitN(p, "=", 2)
    83  		k, v := strings.TrimSpace(kv[0]), strings.TrimSpace(kv[1])
    84  
    85  		if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
    86  			ed := strings.SplitN(v[2:len(v)-1], ":", 2)
    87  			e, d := ed[0], ed[1]
    88  			v = os.Getenv(e)
    89  			if v == "" && d != "" {
    90  				v = d
    91  			}
    92  		}
    93  
    94  		tags[k] = v
    95  	}
    96  
    97  	return tags
    98  }