diff --git a/go.mod b/go.mod index 2b63b14c3dbfe8060e881f531262ed2b5d450062..9933b74ad9187f7a293f2db5fe0e21ee43c61cb9 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( go.opentelemetry.io/otel v1.9.1-0.20220810155701-d96e8d2912af go.opentelemetry.io/otel/exporters/zipkin v1.9.0 go.opentelemetry.io/otel/sdk v1.9.0 + go.opentelemetry.io/otel/trace v1.9.0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 ) diff --git a/tracing/tracing.go b/tracing/tracing.go index 0671df42b6ac4a65c5365967dfc9cb04f35966f5..a20a672f8817ebf2e7924a9e34d86eb1518c75e2 100644 --- a/tracing/tracing.go +++ b/tracing/tracing.go @@ -15,12 +15,16 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/zipkin" "go.opentelemetry.io/otel/sdk/trace" + apitrace "go.opentelemetry.io/otel/trace" ) var ( // Enabled reports whether tracing is globally enabled or not. Enabled bool + // Global Tracer instance. + Tracer apitrace.Tracer + // The active tracing configuration, if Enabled is true. config tracingConfig @@ -37,7 +41,7 @@ type tracingConfig struct { // Read the global tracing configuration file. Its location is // hardcoded, but it can be overriden using the TRACING_CONFIG // environment variable. -func readTracingConfig() error { +func readTracingConfig() (*tracingConfig, error) { // Read and decode configuration. cfgPath := globalTracingConfigPath if s := os.Getenv("TRACING_CONFIG"); s != "" { @@ -45,20 +49,21 @@ func readTracingConfig() error { } data, err := ioutil.ReadFile(cfgPath) if err != nil { - return err + return nil, err } + var config tracingConfig if err := json.Unmarshal(data, &config); err != nil { log.Printf("warning: error in tracing configuration: %v, tracing disabled", err) - return err + return nil, err } if config.ReportURL == "" { log.Printf("warning: tracing configuration contains no report_url, tracing disabled") - return errors.New("no report_url") + return nil, errors.New("no report_url") } - return nil + return &config, nil } // Compute the service name for Zipkin: this is usually the program @@ -78,24 +83,18 @@ func getServiceName() string { // We need to check the configuration as soon as possible, because // it's likely that client transports are created before HTTP servers, // and we need to wrap them with opencensus at creation time. -func init() { - // Kill switch from environment. - if s := os.Getenv("TRACING_ENABLE"); s == "0" { - return - } - - if err := readTracingConfig(); err != nil { - return - } - - Enabled = true -} - func initTracing(endpointAddr string) { - if !Enabled { - return - } initOnce.Do(func() { + // Kill switch from environment. + if s := os.Getenv("TRACING_ENABLE"); s == "0" { + return + } + + config, err := readTracingConfig() + if err != nil { + return + } + ze, err := zipkin.New(config.ReportURL) if err != nil { log.Printf("error creating Zipkin exporter: %v", err) @@ -123,6 +122,7 @@ func initTracing(endpointAddr string) { ) otel.SetTracerProvider(tp) + Tracer = tp.Tracer(endpointAddr) log.Printf("tracing enabled (report_url %s)", config.ReportURL) diff --git a/tracing/tracing_test.go b/tracing/tracing_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a65ba6dfa2fa7c082c79c103d5f15c377cbb2bfc --- /dev/null +++ b/tracing/tracing_test.go @@ -0,0 +1,41 @@ +package tracing + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "net/http/httptest" + "os" + "testing" +) + +func TestTracing(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + }) + httpSrv := httptest.NewServer(h) + defer httpSrv.Close() + + tmpf, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpf.Name()) + defer tmpf.Close() + + if err := json.NewEncoder(tmpf).Encode(&tracingConfig{ + ReportURL: httpSrv.URL, + Sample: "1.0", + }); err != nil { + t.Fatal(err) + } + + os.Setenv("TRACING_ENABLE", "1") + os.Setenv("TRACING_CONFIG", tmpf.Name()) + + Init() + + if !Enabled { + t.Fatal("tracing not enabled") + } +}