github.com/icyphox/x@v0.0.355-0.20220311094250-029bd783e8b8/otelx/otel.go (about)

     1  package otelx
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	"github.com/ory/x/logrusx"
     8  	"github.com/pkg/errors"
     9  	"go.opentelemetry.io/otel"
    10  	"go.opentelemetry.io/otel/exporters/jaeger"
    11  	"go.opentelemetry.io/otel/sdk/resource"
    12  	sdktrace "go.opentelemetry.io/otel/sdk/trace"
    13  	semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
    14  	"go.opentelemetry.io/otel/trace"
    15  )
    16  
    17  type Tracer struct {
    18  	Config *Config
    19  
    20  	l      *logrusx.Logger
    21  	tracer trace.Tracer
    22  	closer io.Closer
    23  }
    24  
    25  // Creates a new tracer. If name is empty, a default tracer name is used
    26  // instead. See: https://godocs.io/go.opentelemetry.io/otel/sdk/trace#TracerProvider.Tracer
    27  func New(name string, l *logrusx.Logger, c *Config) (*Tracer, error) {
    28  	t := &Tracer{Config: c, l: l}
    29  
    30  	if err := t.setup(name); err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	return t, nil
    35  }
    36  
    37  // setup configures a Resource and sets up the TracerProvider
    38  // to send spans to the provided URL.
    39  //
    40  // Endpoint configuration is implicitly read from the below environment
    41  // variables, by default:
    42  //
    43  //    OTEL_EXPORTER_JAEGER_AGENT_HOST
    44  //    OTEL_EXPORTER_JAEGER_AGENT_PORT
    45  //
    46  // Optionally, Config.Providers.Jaeger.LocalAgentAddress can be set.
    47  // NOTE: the default sampling ratio is set to 0.5. You might want to change
    48  // this in production.
    49  func (t *Tracer) setup(name string) error {
    50  	switch t.Config.Provider {
    51  	case "jaeger":
    52  		exp, err := jaeger.New(jaeger.WithAgentEndpoint(
    53  			jaeger.WithAgentHost(t.Config.Providers.Jaeger.LocalAgentHost),
    54  			jaeger.WithAgentPort(fmt.Sprint(t.Config.Providers.Jaeger.LocalAgentPort)),
    55  		))
    56  		if err != nil {
    57  			return err
    58  		}
    59  
    60  		samplingRatio := t.Config.Providers.Jaeger.SamplingRatio
    61  		if samplingRatio == 0 {
    62  			samplingRatio = 0.5
    63  		}
    64  
    65  		tp := sdktrace.NewTracerProvider(
    66  			sdktrace.WithBatcher(exp),
    67  			sdktrace.WithResource(resource.NewWithAttributes(
    68  				semconv.SchemaURL,
    69  				semconv.ServiceNameKey.String(t.Config.ServiceName),
    70  			)),
    71  			sdktrace.WithSampler(sdktrace.TraceIDRatioBased(
    72  				samplingRatio,
    73  			)),
    74  		)
    75  
    76  		otel.SetTracerProvider(tp)
    77  		t.tracer = tp.Tracer(name)
    78  	default:
    79  		return errors.Errorf("unknown tracer: %s", t.Config.Provider)
    80  	}
    81  	return nil
    82  }
    83  
    84  // IsLoaded returns true if the tracer has been loaded.
    85  func (t *Tracer) IsLoaded() bool {
    86  	if t == nil || t.tracer == nil {
    87  		return false
    88  	}
    89  	return true
    90  }
    91  
    92  // Returns the wrapped tracer.
    93  func (t *Tracer) Tracer() trace.Tracer {
    94  	return t.tracer
    95  }