From: Roni Riska Date: Fri, 30 Aug 2019 10:36:14 +0000 (+0300) Subject: Add tracer configuration support X-Git-Tag: v0.0.3^0 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=ddcdb2e4318b9150352f15a7263024fff1ed41e2;p=ric-plt%2Ftracelibgo.git Add tracer configuration support The tracer configuration is done using environment variables. By default a no-op tracer is created. Change-Id: I9c7d0d269c90e0c4588e5b636243f826fc8a4f12 Signed-off-by: Roni Riska --- diff --git a/README.md b/README.md index e11effc..0581318 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ The library creates a configured tracer instance. -ToDO: configuration... ## Usage @@ -49,6 +48,23 @@ The serialized span context is got, for example, from the RMR library. span := opentracing.GlobalTracer().StartSpan("go test span", opentracing.ChildOf(context)) ``` +## Configuration + +The trace library currently supports only [Jaeger](https://www.jaegertracing.io/) [golang client](https://github.com/jaegertracing/jaeger-client-go) tracer implementation. +The configuration is done using environment variables: + +| environment variable | values | default | +| ---------------------------- |------------------------------------ | -------------- | +| TRACING_ENABLED | 1, true, 0, false | false | +| TRACING_JAEGER_SAMPLER_TYPE | const, propabilistic, ratelimiting | const | +| TRACING_JAEGER_SAMPLER_PARAM | float | 0.001 | +| TRACING_JAEGER_AGENT_ADDR | IP addr[:port] | 127.0.0.1:6831 | +| TRACING_JAEGER_LOG_LEVEL | all, error, none | none | + +Meaning of the configuration variables is described in Jaeger web pages. +By default a no-op tracer is created. + + ## Unit testing GO111MODULE=on go mod download diff --git a/go.mod b/go.mod index bfd57df..50ba8e7 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,9 @@ module gerrit.o-ran-sc.org/r/ric-plt/tracelibgo require ( + github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/opentracing/opentracing-go v1.1.0 + github.com/pkg/errors v0.8.1 // indirect github.com/stretchr/testify v1.3.0 github.com/uber/jaeger-client-go v2.16.0+incompatible github.com/uber/jaeger-lib v2.0.0+incompatible // indirect diff --git a/go.sum b/go.sum index f30cee3..0c68a67 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,13 @@ +gerrit.o-ran-sc.org/r/com/golog.git v0.0.1 h1:9RfO/Whehaaq5KiJTT7s+YOzmi9mT1C3HktfhwwMEmw= +gerrit.o-ran-sc.org/r/com/golog.git v0.0.1/go.mod h1:b8YB31U8/4iRpABioeSzGi/YMzOQ/Zq7hrJmmXKqlJk= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/pkg/tracelibgo/tracing.go b/pkg/tracelibgo/tracing.go index df2f45c..f0a3ea2 100644 --- a/pkg/tracelibgo/tracing.go +++ b/pkg/tracelibgo/tracing.go @@ -19,16 +19,121 @@ package tracelibgo import ( + "fmt" "io" + "os" + "strconv" + "strings" "github.com/opentracing/opentracing-go" - "github.com/uber/jaeger-client-go" + jaegercfg "github.com/uber/jaeger-client-go/config" + jaegerlog "github.com/uber/jaeger-client-go/log" ) +const tracingEnabledEnv string = "TRACING_ENABLED" +const jaegerSamplerTypeEnv string = "TRACING_JAEGER_SAMPLER_TYPE" +const jaegerSamplerParamEnv = "TRACING_JAEGER_SAMPLER_PARAM" +const jaegerAgentAddrEnv = "TRACING_JAEGER_AGENT_ADDR" +const jaegerLogLevelEnv = "TRACING_JAEGER_LOG_LEVEL" + +type confMaker struct { + ServiceName string +} + +type logLevel int + +const ( + logAll logLevel = iota + logErr logLevel = iota + logNone logLevel = iota +) + +func (cm *confMaker) GetEnv(envName string, defval string) (retval string) { + retval = os.Getenv(envName) + if retval == "" { + retval = defval + } + return +} + +func (cm *confMaker) IsTracingEnabled() bool { + val := cm.GetEnv(tracingEnabledEnv, "false") + if val == "1" || strings.ToLower(val) == "true" { + return true + } + return false +} + +func createDisabledTracer(name string) (opentracing.Tracer, io.Closer) { + if name == "" { + name = "dummy" + } + cfg := jaegercfg.Configuration{ + ServiceName: name, + Disabled: true, + } + tracer, closer, err := cfg.NewTracer() + if err != nil { + fmt.Fprintln(os.Stderr, "tracelibgo: trace creation error: ", err.Error()) + } + return tracer, closer +} + +func (cm *confMaker) getSamplerConfig() jaegercfg.SamplerConfig { + samplerType := cm.GetEnv(jaegerSamplerTypeEnv, "const") + param, err := strconv.ParseFloat(cm.GetEnv(jaegerSamplerParamEnv, "0.001"), 64) + if err != nil { + param = 0 + } + return jaegercfg.SamplerConfig{Type: samplerType, Param: param} +} + +func (cm *confMaker) getReporterConfig() jaegercfg.ReporterConfig { + agentHostPort := cm.GetEnv(jaegerAgentAddrEnv, "127.0.0.1:6831") + if !strings.Contains(agentHostPort, ":") { + agentHostPort += ":6831" + } + return jaegercfg.ReporterConfig{LogSpans: cm.getLoggingLevel() == logAll, LocalAgentHostPort: agentHostPort} +} + +func (cm *confMaker) getLoggingLevel() logLevel { + level := strings.ToLower(cm.GetEnv(jaegerLogLevelEnv, "error")) + switch level { + case "error": + return logErr + case "all": + return logAll + default: + return logNone + } +} + // CreateTracer creates a tracer entry func CreateTracer(name string) (opentracing.Tracer, io.Closer) { - tracer, closer := jaeger.NewTracer(name, - jaeger.NewConstSampler(false), - jaeger.NewNullReporter()) + + cm := confMaker{name} + if !cm.IsTracingEnabled() { + return createDisabledTracer(name) + } + sampler := cm.getSamplerConfig() + reporter := cm.getReporterConfig() + cfg := jaegercfg.Configuration{ + ServiceName: name, + Disabled: false, + Sampler: &sampler, + Reporter: &reporter, + } + var jaegerLoggerOpt jaegercfg.Option + switch cm.getLoggingLevel() { + case logAll, logErr: + jaegerLoggerOpt = jaegercfg.Logger(jaegerlog.StdLogger) + default: + jaegerLoggerOpt = jaegercfg.Logger(nil) + } + tracer, closer, err := cfg.NewTracer(jaegerLoggerOpt) + if err != nil { + fmt.Fprintln(os.Stderr, "tracelibgo: cannot init tracer: "+err.Error()) + return createDisabledTracer(name) + } return tracer, closer } diff --git a/pkg/tracelibgo/tracing_test.go b/pkg/tracelibgo/tracing_test.go index 86a61ce..e5ede67 100644 --- a/pkg/tracelibgo/tracing_test.go +++ b/pkg/tracelibgo/tracing_test.go @@ -18,15 +18,114 @@ package tracelibgo import ( + "os" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" ) -func TestTracerCreate(t *testing.T) { +type ConfMakerTestSuite struct { + suite.Suite + cm confMaker +} + +func (suite *ConfMakerTestSuite) SetupTest() { + suite.cm = confMaker{"foo"} +} + +func (suite *ConfMakerTestSuite) TearDownTest() { + os.Unsetenv(tracingEnabledEnv) + os.Unsetenv(jaegerSamplerTypeEnv) + os.Unsetenv(jaegerSamplerParamEnv) + os.Unsetenv(jaegerAgentAddrEnv) + os.Unsetenv(jaegerLogLevelEnv) +} + +func (suite *ConfMakerTestSuite) TestTracingIsDisabledByDefault() { + suite.False(suite.cm.IsTracingEnabled()) +} + +func (suite *ConfMakerTestSuite) TestTracingCanBeEnabledWithEnvVar() { + os.Setenv(tracingEnabledEnv, "1") + suite.True(suite.cm.IsTracingEnabled()) + os.Setenv(tracingEnabledEnv, "true") + suite.True(suite.cm.IsTracingEnabled()) +} + +func (suite *ConfMakerTestSuite) TestTracingEnabledWithUnknownValueResultsDisabled() { + os.Setenv(tracingEnabledEnv, "0") + suite.False(suite.cm.IsTracingEnabled()) + os.Setenv(tracingEnabledEnv, "foo") + suite.False(suite.cm.IsTracingEnabled()) +} + +func (suite *ConfMakerTestSuite) TestSamplerTypeDefaultIsConst() { + suite.Equal("const", suite.cm.getSamplerConfig().Type) +} + +func (suite *ConfMakerTestSuite) TestSamplerTypeParamDefault() { + suite.Equal(0.001, suite.cm.getSamplerConfig().Param) +} + +func (suite *ConfMakerTestSuite) TestSamplerTypeCanBeDefined() { + os.Setenv(jaegerSamplerTypeEnv, "probabilistic") + suite.Equal("probabilistic", suite.cm.getSamplerConfig().Type) +} + +func (suite *ConfMakerTestSuite) TestIfSamplerParamIsInvalidZeroValueIsUsed() { + os.Setenv(jaegerSamplerParamEnv, "foo") + suite.Equal(0.0, suite.cm.getSamplerConfig().Param) +} + +func (suite *ConfMakerTestSuite) TestAgentAddrCanBeDefined() { + os.Setenv(jaegerAgentAddrEnv, "1.1.1.1:1111") + suite.Equal("1.1.1.1:1111", suite.cm.getReporterConfig().LocalAgentHostPort) +} + +func (suite *ConfMakerTestSuite) TestAgentAddressPortIsOptional() { + os.Setenv(jaegerAgentAddrEnv, "1.1.1.1") + suite.Equal("1.1.1.1:6831", suite.cm.getReporterConfig().LocalAgentHostPort) +} + +func (suite *ConfMakerTestSuite) TestLoggingLevelDefaultIsErr() { + suite.Equal(logErr, suite.cm.getLoggingLevel()) +} + +func (suite *ConfMakerTestSuite) TestLoggingLevelCanBeConfigured() { + os.Setenv(jaegerLogLevelEnv, "error") + suite.Equal(logErr, suite.cm.getLoggingLevel()) + os.Setenv(jaegerLogLevelEnv, "all") + suite.Equal(logAll, suite.cm.getLoggingLevel()) + os.Setenv(jaegerLogLevelEnv, "none") + suite.Equal(logNone, suite.cm.getLoggingLevel()) +} + +func (suite *ConfMakerTestSuite) TestConfiguredTracerCreate() { + os.Setenv(tracingEnabledEnv, "1") + os.Setenv(jaegerSamplerParamEnv, "const") + os.Setenv(jaegerSamplerParamEnv, "1") + os.Setenv(jaegerAgentAddrEnv, "127.0.0.1:6831") + tracer, closer := CreateTracer("foo") + suite.NotNil(tracer) + suite.NotNil(closer) +} + +func (suite *ConfMakerTestSuite) TestIfTracerCreationFailsDisabledTracerIsReturned() { + os.Setenv(tracingEnabledEnv, "1") + tracer, closer := CreateTracer("") // Empty name is an error + suite.NotNil(tracer) + suite.NotNil(closer) +} + +func TestConfMakerSuite(t *testing.T) { + suite.Run(t, new(ConfMakerTestSuite)) +} + +func TestDefaultTracerCreate(t *testing.T) { tracer, closer := CreateTracer("foo") assert.NotNil(t, tracer) assert.NotNil(t, closer) err := closer.Close() assert.Nil(t, err) } -