vitess.io/vitess@v0.16.2/go/trace/plugin_jaeger.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package trace
    18  
    19  import (
    20  	"io"
    21  	"os"
    22  
    23  	"github.com/opentracing/opentracing-go"
    24  	"github.com/spf13/pflag"
    25  	"github.com/uber/jaeger-client-go"
    26  	"github.com/uber/jaeger-client-go/config"
    27  
    28  	"vitess.io/vitess/go/flagutil"
    29  	"vitess.io/vitess/go/vt/log"
    30  )
    31  
    32  /*
    33  This file makes it easy to build Vitess without including the Jaeger binaries.
    34  All that is needed is to delete this file. OpenTracing binaries will still be
    35  included but nothing Jaeger specific.
    36  */
    37  
    38  var (
    39  	agentHost    string
    40  	samplingType = flagutil.NewOptionalString("const")
    41  	samplingRate = flagutil.NewOptionalFloat64(0.1)
    42  )
    43  
    44  func init() {
    45  	// If compiled with plugin_jaeger, ensure that trace.RegisterFlags includes
    46  	// jaeger tracing flags.
    47  	pluginFlags = append(pluginFlags, func(fs *pflag.FlagSet) {
    48  		fs.StringVar(&agentHost, "jaeger-agent-host", "", "host and port to send spans to. if empty, no tracing will be done")
    49  		fs.Var(samplingType, "tracing-sampling-type", "sampling strategy to use for jaeger. possible values are 'const', 'probabilistic', 'rateLimiting', or 'remote'")
    50  		fs.Var(samplingRate, "tracing-sampling-rate", "sampling rate for the probabilistic jaeger sampler")
    51  	})
    52  }
    53  
    54  // newJagerTracerFromEnv will instantiate a tracingService implemented by Jaeger,
    55  // taking configuration from environment variables. Available properties are:
    56  // JAEGER_SERVICE_NAME -- If this is set, the service name used in code will be ignored and this value used instead
    57  // JAEGER_RPC_METRICS
    58  // JAEGER_TAGS
    59  // JAEGER_SAMPLER_TYPE
    60  // JAEGER_SAMPLER_PARAM
    61  // JAEGER_SAMPLER_MANAGER_HOST_PORT
    62  // JAEGER_SAMPLER_MAX_OPERATIONS
    63  // JAEGER_SAMPLER_REFRESH_INTERVAL
    64  // JAEGER_REPORTER_MAX_QUEUE_SIZE
    65  // JAEGER_REPORTER_FLUSH_INTERVAL
    66  // JAEGER_REPORTER_LOG_SPANS
    67  // JAEGER_ENDPOINT
    68  // JAEGER_USER
    69  // JAEGER_PASSWORD
    70  // JAEGER_AGENT_HOST
    71  // JAEGER_AGENT_PORT
    72  func newJagerTracerFromEnv(serviceName string) (tracingService, io.Closer, error) {
    73  	cfg, err := config.FromEnv()
    74  	if err != nil {
    75  		return nil, nil, err
    76  	}
    77  	if cfg.ServiceName == "" {
    78  		cfg.ServiceName = serviceName
    79  	}
    80  
    81  	// Allow command line args to override environment variables.
    82  	if agentHost != "" {
    83  		cfg.Reporter.LocalAgentHostPort = agentHost
    84  	}
    85  	log.Infof("Tracing to: %v as %v", cfg.Reporter.LocalAgentHostPort, cfg.ServiceName)
    86  
    87  	if os.Getenv("JAEGER_SAMPLER_PARAM") == "" {
    88  		// If the environment variable was not set, we take the flag regardless
    89  		// of whether it was explicitly set on the command line.
    90  		cfg.Sampler.Param = samplingRate.Get()
    91  	} else if samplingRate.IsSet() {
    92  		// If the environment variable was set, but the user also explicitly
    93  		// passed the command line flag, the flag takes precedence.
    94  		cfg.Sampler.Param = samplingRate.Get()
    95  	}
    96  
    97  	if samplingType.IsSet() {
    98  		cfg.Sampler.Type = samplingType.Get()
    99  	} else if cfg.Sampler.Type == "" {
   100  		log.Infof("--tracing-sampler-type was not set, and JAEGER_SAMPLER_TYPE was not set, defaulting to const sampler")
   101  		cfg.Sampler.Type = jaeger.SamplerTypeConst
   102  	}
   103  
   104  	log.Infof("Tracing sampler type %v (param: %v)", cfg.Sampler.Type, cfg.Sampler.Param)
   105  
   106  	var opts []config.Option
   107  	if enableLogging {
   108  		opts = append(opts, config.Logger(&traceLogger{}))
   109  	} else if cfg.Reporter.LogSpans {
   110  		log.Warningf("JAEGER_REPORTER_LOG_SPANS was set, but --tracing-enable-logging was not; spans will not be logged")
   111  	}
   112  
   113  	tracer, closer, err := cfg.NewTracer(opts...)
   114  
   115  	if err != nil {
   116  		return nil, &nilCloser{}, err
   117  	}
   118  
   119  	opentracing.SetGlobalTracer(tracer)
   120  
   121  	return openTracingService{Tracer: &jaegerTracer{actual: tracer}}, closer, nil
   122  }
   123  
   124  func init() {
   125  	tracingBackendFactories["opentracing-jaeger"] = newJagerTracerFromEnv
   126  }
   127  
   128  var _ tracer = (*jaegerTracer)(nil)
   129  
   130  type jaegerTracer struct {
   131  	actual opentracing.Tracer
   132  }
   133  
   134  func (jt *jaegerTracer) GetOpenTracingTracer() opentracing.Tracer {
   135  	return jt.actual
   136  }