github.com/thanos-io/thanos@v0.32.5/pkg/tracing/otlp/otlp.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package otlp 5 6 import ( 7 "context" 8 "strconv" 9 "strings" 10 11 "github.com/thanos-io/thanos/pkg/tracing/migration" 12 13 "github.com/go-kit/log" 14 "github.com/go-kit/log/level" 15 "github.com/pkg/errors" 16 "go.opentelemetry.io/otel/exporters/otlp/otlptrace" 17 "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" 18 "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" 19 "go.opentelemetry.io/otel/sdk/resource" 20 tracesdk "go.opentelemetry.io/otel/sdk/trace" 21 semconv "go.opentelemetry.io/otel/semconv/v1.7.0" 22 _ "google.golang.org/grpc/encoding/gzip" 23 "gopkg.in/yaml.v2" 24 ) 25 26 const ( 27 TracingClientGRPC string = "grpc" 28 TracingClientHTTP string = "http" 29 AlwaysSample string = "alwayssample" 30 NeverSample string = "neversample" 31 RatioBasedSample string = "traceidratiobased" 32 ) 33 34 // NewOTELTracer returns an OTLP exporter based tracer. 35 func NewTracerProvider(ctx context.Context, logger log.Logger, conf []byte) (*tracesdk.TracerProvider, error) { 36 config := Config{} 37 if err := yaml.Unmarshal(conf, &config); err != nil { 38 return nil, err 39 } 40 41 var exporter *otlptrace.Exporter 42 var err error 43 switch strings.ToLower(config.ClientType) { 44 case TracingClientHTTP: 45 options := traceHTTPOptions(config) 46 47 client := otlptracehttp.NewClient(options...) 48 exporter, err = otlptrace.New(ctx, client) 49 if err != nil { 50 return nil, err 51 } 52 53 case TracingClientGRPC: 54 options := traceGRPCOptions(config) 55 client := otlptracegrpc.NewClient(options...) 56 exporter, err = otlptrace.New(ctx, client) 57 if err != nil { 58 return nil, err 59 } 60 61 default: 62 return nil, errors.New("otlp: invalid client type. Only 'http' and 'grpc' are accepted. ") 63 } 64 65 processor := tracesdk.NewBatchSpanProcessor(exporter) 66 sampler, err := getSampler(config) 67 if err != nil { 68 logger.Log(err) 69 } 70 tp := newTraceProvider(ctx, processor, logger, config.ServiceName, sampler) 71 72 return tp, nil 73 } 74 75 func newTraceProvider(ctx context.Context, processor tracesdk.SpanProcessor, logger log.Logger, serviceName string, sampler tracesdk.Sampler) *tracesdk.TracerProvider { 76 var ( 77 r *resource.Resource 78 err error 79 ) 80 if serviceName != "" { 81 r, err = resource.New( 82 ctx, 83 resource.WithAttributes(semconv.ServiceNameKey.String(serviceName)), 84 ) 85 } else { 86 r, err = resource.New( 87 ctx, 88 ) 89 } 90 if err != nil { 91 level.Warn(logger).Log("msg", "jaeger: detecting resources for tracing provider failed", "err", err) 92 } 93 94 tp := tracesdk.NewTracerProvider( 95 tracesdk.WithSpanProcessor(processor), 96 tracesdk.WithResource(r), 97 tracesdk.WithSampler( 98 migration.SamplerWithOverride( 99 sampler, migration.ForceTracingAttributeKey, 100 ), 101 ), 102 ) 103 return tp 104 } 105 106 func getSampler(config Config) (tracesdk.Sampler, error) { 107 switch strings.ToLower(config.SamplerType) { 108 case AlwaysSample: 109 return tracesdk.ParentBased(tracesdk.AlwaysSample()), nil 110 case NeverSample: 111 return tracesdk.ParentBased(tracesdk.NeverSample()), nil 112 case RatioBasedSample: 113 arg, err := strconv.ParseFloat(config.SamplerParam, 64) 114 if err != nil { 115 return tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0)), err 116 } 117 return tracesdk.ParentBased(tracesdk.TraceIDRatioBased(arg)), nil 118 } 119 120 return tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0)), nil 121 }