1// Copyright (c) 2017 Uber Technologies, Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package config 16 17import ( 18 opentracing "github.com/opentracing/opentracing-go" 19 "github.com/uber/jaeger-lib/metrics" 20 21 "github.com/uber/jaeger-client-go" 22) 23 24// Option is a function that sets some option on the client. 25type Option func(c *Options) 26 27// Options control behavior of the client. 28type Options struct { 29 metrics metrics.Factory 30 logger jaeger.Logger 31 reporter jaeger.Reporter 32 sampler jaeger.Sampler 33 contribObservers []jaeger.ContribObserver 34 observers []jaeger.Observer 35 gen128Bit bool 36 poolSpans bool 37 zipkinSharedRPCSpan bool 38 maxTagValueLength int 39 noDebugFlagOnForcedSampling bool 40 tags []opentracing.Tag 41 injectors map[interface{}]jaeger.Injector 42 extractors map[interface{}]jaeger.Extractor 43} 44 45// Metrics creates an Option that initializes Metrics in the tracer, 46// which is used to emit statistics about spans. 47func Metrics(factory metrics.Factory) Option { 48 return func(c *Options) { 49 c.metrics = factory 50 } 51} 52 53// Logger can be provided to log Reporter errors, as well as to log spans 54// if Reporter.LogSpans is set to true. 55func Logger(logger jaeger.Logger) Option { 56 return func(c *Options) { 57 c.logger = logger 58 } 59} 60 61// Reporter can be provided explicitly to override the configuration. 62// Useful for testing, e.g. by passing InMemoryReporter. 63func Reporter(reporter jaeger.Reporter) Option { 64 return func(c *Options) { 65 c.reporter = reporter 66 } 67} 68 69// Sampler can be provided explicitly to override the configuration. 70func Sampler(sampler jaeger.Sampler) Option { 71 return func(c *Options) { 72 c.sampler = sampler 73 } 74} 75 76// Observer can be registered with the Tracer to receive notifications about new Spans. 77func Observer(observer jaeger.Observer) Option { 78 return func(c *Options) { 79 c.observers = append(c.observers, observer) 80 } 81} 82 83// ContribObserver can be registered with the Tracer to receive notifications 84// about new spans. 85func ContribObserver(observer jaeger.ContribObserver) Option { 86 return func(c *Options) { 87 c.contribObservers = append(c.contribObservers, observer) 88 } 89} 90 91// Gen128Bit specifies whether to generate 128bit trace IDs. 92func Gen128Bit(gen128Bit bool) Option { 93 return func(c *Options) { 94 c.gen128Bit = gen128Bit 95 } 96} 97 98// PoolSpans specifies whether to pool spans 99func PoolSpans(poolSpans bool) Option { 100 return func(c *Options) { 101 c.poolSpans = poolSpans 102 } 103} 104 105// ZipkinSharedRPCSpan creates an option that enables sharing span ID between client 106// and server spans a la zipkin. If false, client and server spans will be assigned 107// different IDs. 108func ZipkinSharedRPCSpan(zipkinSharedRPCSpan bool) Option { 109 return func(c *Options) { 110 c.zipkinSharedRPCSpan = zipkinSharedRPCSpan 111 } 112} 113 114// MaxTagValueLength can be provided to override the default max tag value length. 115func MaxTagValueLength(maxTagValueLength int) Option { 116 return func(c *Options) { 117 c.maxTagValueLength = maxTagValueLength 118 } 119} 120 121// NoDebugFlagOnForcedSampling can be used to decide whether debug flag will be set or not 122// when calling span.setSamplingPriority to force sample a span. 123func NoDebugFlagOnForcedSampling(noDebugFlagOnForcedSampling bool) Option { 124 return func(c *Options) { 125 c.noDebugFlagOnForcedSampling = noDebugFlagOnForcedSampling 126 } 127} 128 129// Tag creates an option that adds a tracer-level tag. 130func Tag(key string, value interface{}) Option { 131 return func(c *Options) { 132 c.tags = append(c.tags, opentracing.Tag{Key: key, Value: value}) 133 } 134} 135 136// Injector registers an Injector with the given format. 137func Injector(format interface{}, injector jaeger.Injector) Option { 138 return func(c *Options) { 139 c.injectors[format] = injector 140 } 141} 142 143// Extractor registers an Extractor with the given format. 144func Extractor(format interface{}, extractor jaeger.Extractor) Option { 145 return func(c *Options) { 146 c.extractors[format] = extractor 147 } 148} 149 150func applyOptions(options ...Option) Options { 151 opts := Options{ 152 injectors: make(map[interface{}]jaeger.Injector), 153 extractors: make(map[interface{}]jaeger.Extractor), 154 } 155 for _, option := range options { 156 option(&opts) 157 } 158 if opts.metrics == nil { 159 opts.metrics = metrics.NullFactory 160 } 161 if opts.logger == nil { 162 opts.logger = jaeger.NullLogger 163 } 164 return opts 165} 166