github.com/Jeffail/benthos/v3@v3.65.0/lib/tracer/jaeger.go (about) 1 package tracer 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 "time" 8 9 "github.com/Jeffail/benthos/v3/internal/docs" 10 "github.com/opentracing/opentracing-go" 11 "github.com/uber/jaeger-client-go" 12 jaegercfg "github.com/uber/jaeger-client-go/config" 13 ) 14 15 //------------------------------------------------------------------------------ 16 17 func init() { 18 Constructors[TypeJaeger] = TypeSpec{ 19 constructor: NewJaeger, 20 Summary: ` 21 Send tracing events to a [Jaeger](https://www.jaegertracing.io/) agent or collector.`, 22 FieldSpecs: docs.FieldSpecs{ 23 docs.FieldCommon("agent_address", "The address of a Jaeger agent to send tracing events to.", "jaeger-agent:6831"), 24 docs.FieldCommon("collector_url", "The URL of a Jaeger collector to send tracing events to. If set, this will override `agent_address`.", 25 "https://jaeger-collector:14268/api/traces").AtVersion("3.38.0"), 26 docs.FieldCommon("service_name", "A name to provide for this service."), 27 docs.FieldCommon("sampler_type", "The sampler type to use.").HasAnnotatedOptions( 28 "const", "A constant decision for all traces, either 1 or 0.", 29 "probabilistic", "The sampler makes a random sampling decision with the probability of sampling equal to the value of sampler param.", 30 "ratelimiting", "The sampler uses a leaky bucket rate limiter to ensure that traces are sampled with a certain constant rate.", 31 "remote", "The sampler consults Jaeger agent for the appropriate sampling strategy to use in the current service.", 32 ), 33 docs.FieldAdvanced("sampler_manager_address", "An optional address of a sampler manager."), 34 docs.FieldFloat("sampler_param", "A parameter to use for sampling. This field is unused for some sampling types.").Advanced(), 35 docs.FieldString("tags", "A map of tags to add to tracing spans.").Map().Advanced(), 36 docs.FieldCommon("flush_interval", "The period of time between each flush of tracing spans."), 37 }, 38 } 39 } 40 41 //------------------------------------------------------------------------------ 42 43 // JaegerConfig is config for the Jaeger metrics type. 44 type JaegerConfig struct { 45 AgentAddress string `json:"agent_address" yaml:"agent_address"` 46 CollectorURL string `json:"collector_url" yaml:"collector_url"` 47 ServiceName string `json:"service_name" yaml:"service_name"` 48 SamplerType string `json:"sampler_type" yaml:"sampler_type"` 49 SamplerManagerAddress string `json:"sampler_manager_address" yaml:"sampler_manager_address"` 50 SamplerParam float64 `json:"sampler_param" yaml:"sampler_param"` 51 Tags map[string]string `json:"tags" yaml:"tags"` 52 FlushInterval string `json:"flush_interval" yaml:"flush_interval"` 53 } 54 55 // NewJaegerConfig creates an JaegerConfig struct with default values. 56 func NewJaegerConfig() JaegerConfig { 57 return JaegerConfig{ 58 AgentAddress: "localhost:6831", 59 ServiceName: "benthos", 60 SamplerType: "const", 61 SamplerManagerAddress: "", 62 SamplerParam: 1.0, 63 Tags: map[string]string{}, 64 FlushInterval: "", 65 } 66 } 67 68 //------------------------------------------------------------------------------ 69 70 // Jaeger is a tracer with the capability to push spans to a Jaeger instance. 71 type Jaeger struct { 72 closer io.Closer 73 } 74 75 // NewJaeger creates and returns a new Jaeger object. 76 func NewJaeger(config Config, opts ...func(Type)) (Type, error) { 77 j := &Jaeger{} 78 79 for _, opt := range opts { 80 opt(j) 81 } 82 83 var sampler *jaegercfg.SamplerConfig 84 if sType := config.Jaeger.SamplerType; len(sType) > 0 { 85 sampler = &jaegercfg.SamplerConfig{ 86 Param: config.Jaeger.SamplerParam, 87 SamplingServerURL: config.Jaeger.SamplerManagerAddress, 88 } 89 switch strings.ToLower(sType) { 90 case "const": 91 sampler.Type = jaeger.SamplerTypeConst 92 case "probabilistic": 93 sampler.Type = jaeger.SamplerTypeProbabilistic 94 case "ratelimiting": 95 sampler.Type = jaeger.SamplerTypeRateLimiting 96 case "remote": 97 sampler.Type = jaeger.SamplerTypeRemote 98 default: 99 return nil, fmt.Errorf("unrecognised sampler type: %v", sType) 100 } 101 } 102 103 cfg := jaegercfg.Configuration{ 104 ServiceName: config.Jaeger.ServiceName, 105 Sampler: sampler, 106 } 107 108 if tags := config.Jaeger.Tags; len(tags) > 0 { 109 var jTags []opentracing.Tag 110 for k, v := range config.Jaeger.Tags { 111 jTags = append(jTags, opentracing.Tag{ 112 Key: k, 113 Value: v, 114 }) 115 } 116 cfg.Tags = jTags 117 } 118 119 reporterConf := &jaegercfg.ReporterConfig{} 120 121 if i := config.Jaeger.FlushInterval; len(i) > 0 { 122 flushInterval, err := time.ParseDuration(i) 123 if err != nil { 124 return nil, fmt.Errorf("failed to parse flush interval '%s': %v", i, err) 125 } 126 reporterConf.BufferFlushInterval = flushInterval 127 cfg.Reporter = reporterConf 128 } 129 130 if i := config.Jaeger.AgentAddress; len(i) > 0 { 131 reporterConf.LocalAgentHostPort = i 132 cfg.Reporter = reporterConf 133 } 134 135 if i := config.Jaeger.CollectorURL; len(i) > 0 { 136 reporterConf.CollectorEndpoint = i 137 } 138 139 tracer, closer, err := cfg.NewTracer() 140 if err != nil { 141 return nil, err 142 } 143 opentracing.SetGlobalTracer(tracer) 144 j.closer = closer 145 146 return j, nil 147 } 148 149 //------------------------------------------------------------------------------ 150 151 // Close stops the tracer. 152 func (j *Jaeger) Close() error { 153 if j.closer != nil { 154 j.closer.Close() 155 j.closer = nil 156 } 157 return nil 158 } 159 160 //------------------------------------------------------------------------------