...

Source file src/github.com/ory/x/tracing/tracer.go

Documentation: github.com/ory/x/tracing

     1  package tracing
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/opentracing/opentracing-go"
     9  	"github.com/pkg/errors"
    10  
    11  	"github.com/ory/x/logrusx"
    12  
    13  	zipkinOT "github.com/openzipkin-contrib/zipkin-go-opentracing"
    14  	"github.com/openzipkin/zipkin-go"
    15  	zipkinHttp "github.com/openzipkin/zipkin-go/reporter/http"
    16  
    17  	jaegerConf "github.com/uber/jaeger-client-go/config"
    18  	jaegerZipkin "github.com/uber/jaeger-client-go/zipkin"
    19  
    20  	datadogOpentracer "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer"
    21  	datadogTracer "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
    22  
    23  	"go.elastic.co/apm"
    24  	"go.elastic.co/apm/module/apmot"
    25  )
    26  
    27  // Tracer encapsulates tracing abilities.
    28  type Tracer struct {
    29  	Config *Config
    30  
    31  	l      *logrusx.Logger
    32  	tracer opentracing.Tracer
    33  	closer io.Closer
    34  }
    35  
    36  func New(l *logrusx.Logger, c *Config) (*Tracer, error) {
    37  	t := &Tracer{Config: c, l: l}
    38  
    39  	if err := t.setup(); err != nil {
    40  		return nil, err
    41  	}
    42  
    43  	return t, nil
    44  }
    45  
    46  // setup sets up the tracer. Currently supports jaeger.
    47  func (t *Tracer) setup() error {
    48  	switch strings.ToLower(t.Config.Provider) {
    49  	case "jaeger":
    50  		jc, err := jaegerConf.FromEnv()
    51  
    52  		if err != nil {
    53  			return err
    54  		}
    55  
    56  		if t.Config.Jaeger.SamplerServerURL != "" {
    57  			jc.Sampler.SamplingServerURL = t.Config.Jaeger.SamplerServerURL
    58  		}
    59  
    60  		if t.Config.Jaeger.SamplerType != "" {
    61  			jc.Sampler.Type = t.Config.Jaeger.SamplerType
    62  		}
    63  
    64  		if t.Config.Jaeger.SamplerValue != 0 {
    65  			jc.Sampler.Param = t.Config.Jaeger.SamplerValue
    66  		}
    67  
    68  		if t.Config.Jaeger.LocalAgentHostPort != "" {
    69  			jc.Reporter.LocalAgentHostPort = t.Config.Jaeger.LocalAgentHostPort
    70  		}
    71  
    72  		var configs []jaegerConf.Option
    73  
    74  		// This works in other jaeger clients, but is not part of jaeger-client-go
    75  		if t.Config.Jaeger.Propagation == "b3" {
    76  			zipkinPropagator := jaegerZipkin.NewZipkinB3HTTPHeaderPropagator()
    77  			configs = append(
    78  				configs,
    79  				jaegerConf.Injector(opentracing.HTTPHeaders, zipkinPropagator),
    80  				jaegerConf.Extractor(opentracing.HTTPHeaders, zipkinPropagator),
    81  			)
    82  		}
    83  
    84  		closer, err := jc.InitGlobalTracer(
    85  			t.Config.ServiceName,
    86  			configs...,
    87  		)
    88  
    89  		if err != nil {
    90  			return err
    91  		}
    92  
    93  		t.closer = closer
    94  		t.tracer = opentracing.GlobalTracer()
    95  		t.l.Infof("Jaeger tracer configured!")
    96  	case "zipkin":
    97  		if t.Config.Zipkin.ServerURL == "" {
    98  			return errors.Errorf("Zipkin's server url is required")
    99  		}
   100  
   101  		reporter := zipkinHttp.NewReporter(t.Config.Zipkin.ServerURL)
   102  
   103  		endpoint, err := zipkin.NewEndpoint(t.Config.ServiceName, "")
   104  
   105  		if err != nil {
   106  			return err
   107  		}
   108  
   109  		nativeTracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint))
   110  
   111  		if err != nil {
   112  			return err
   113  		}
   114  
   115  		opentracing.SetGlobalTracer(zipkinOT.Wrap(nativeTracer))
   116  
   117  		t.closer = reporter
   118  		t.tracer = opentracing.GlobalTracer()
   119  		t.l.Infof("Zipkin tracer configured!")
   120  	case "datadog":
   121  		var serviceName = os.Getenv("DD_SERVICE")
   122  		if serviceName == "" {
   123  			serviceName = t.Config.ServiceName
   124  		}
   125  
   126  		opentracing.SetGlobalTracer(datadogOpentracer.New(datadogTracer.WithService(serviceName)))
   127  
   128  		t.closer = datadogCloser{}
   129  		t.tracer = opentracing.GlobalTracer()
   130  		t.l.Infof("DataDog tracer configured!")
   131  	case "elastic-apm":
   132  		var serviceName = os.Getenv("ELASTIC_APM_SERVICE_NAME")
   133  		if serviceName == "" {
   134  			serviceName = t.Config.ServiceName
   135  		}
   136  
   137  		tr, err := apm.NewTracer(serviceName, "")
   138  		if err != nil {
   139  			return err
   140  		}
   141  		opentracing.SetGlobalTracer(apmot.New(apmot.WithTracer(tr)))
   142  
   143  		//t.closer = tr.Close
   144  		t.tracer = opentracing.GlobalTracer()
   145  		t.l.Infof("Elastic APM tracer configured!")
   146  
   147  	case "":
   148  		t.l.Infof("No tracer configured - skipping tracing setup")
   149  	default:
   150  		return errors.Errorf("unknown tracer: %s", t.Config.Provider)
   151  	}
   152  	return nil
   153  }
   154  
   155  // IsLoaded returns true if the tracer has been loaded.
   156  func (t *Tracer) IsLoaded() bool {
   157  	if t == nil || t.tracer == nil {
   158  		return false
   159  	}
   160  	return true
   161  }
   162  
   163  // Tracer returns the wrapped tracer
   164  func (t *Tracer) Tracer() opentracing.Tracer {
   165  	return t.tracer
   166  }
   167  
   168  // Close closes the tracer.
   169  func (t *Tracer) Close() {
   170  	if t.closer != nil {
   171  		err := t.closer.Close()
   172  		if err != nil {
   173  			t.l.WithError(err).Error("Unable to close tracer.")
   174  		}
   175  	}
   176  }
   177  

View as plain text