The tracer configuration is done using environment variables.
By default a no-op tracer is created.
Change-Id: I9c7d0d269c90e0c4588e5b636243f826fc8a4f12
Signed-off-by: Roni Riska <roni.riska@nokia.com>
The library creates a configured tracer instance.
-ToDO: configuration...
## Usage
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
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
+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=
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
}
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)
}
-