diff --git a/instrumentation/opentelemetry/init.go b/instrumentation/opentelemetry/init.go index 40cfe1b..3fe20a5 100644 --- a/instrumentation/opentelemetry/init.go +++ b/instrumentation/opentelemetry/init.go @@ -39,15 +39,18 @@ import ( "google.golang.org/grpc/resolver" ) -var batchTimeout = time.Duration(200) * time.Millisecond - var ( - traceProviders map[string]*sdktrace.TracerProvider - globalSampler sdktrace.Sampler - initialized = false - enabled = false - mu sync.Mutex - exporterFactory func() (sdktrace.SpanExporter, error) + batchTimeout = time.Duration(200) * time.Millisecond + traceProviders map[string]*sdktrace.TracerProvider + globalSampler sdktrace.Sampler + initialized = false + enabled = false + mu sync.Mutex + exporterFactory func() (sdktrace.SpanExporter, error) + versionInfoAttributes = []attribute.KeyValue{ + semconv.TelemetrySDKNameKey.String("hypertrace"), + semconv.TelemetrySDKVersionKey.String(version.Version), + } ) func makePropagator(formats []config.PropagationFormat) propagation.TextMapPropagator { @@ -208,12 +211,13 @@ func createCaCertPoolFromFile(certFile string) *x509.CertPool { // Init initializes opentelemetry tracing and returns a shutdown function to flush data immediately // on a termination signal. func Init(cfg *config.AgentConfig) func() { - return InitWithSpanProcessorWrapper(cfg, nil) + return InitWithSpanProcessorWrapper(cfg, nil, versionInfoAttributes) } // InitWithSpanProcessorWrapper initializes opentelemetry tracing with a wrapper over span processor // and returns a shutdown function to flush data immediately on a termination signal. -func InitWithSpanProcessorWrapper(cfg *config.AgentConfig, wrapper SpanProcessorWrapper) func() { +func InitWithSpanProcessorWrapper(cfg *config.AgentConfig, wrapper SpanProcessorWrapper, + versionInfoAttrs []attribute.KeyValue) func() { mu.Lock() defer mu.Unlock() if initialized { @@ -237,7 +241,7 @@ func InitWithSpanProcessorWrapper(cfg *config.AgentConfig, wrapper SpanProcessor } // Initialize metrics - metricsShutdownFn := initializeMetrics(cfg) + metricsShutdownFn := initializeMetrics(cfg, versionInfoAttrs) exporterFactory = makeExporterFactory(cfg) @@ -256,7 +260,8 @@ func InitWithSpanProcessorWrapper(cfg *config.AgentConfig, wrapper SpanProcessor resources, err := resource.New( context.Background(), - resource.WithAttributes(createResources(cfg.GetServiceName().GetValue(), cfg.ResourceAttributes)...), + resource.WithAttributes(createResources(cfg.GetServiceName().GetValue(), cfg.ResourceAttributes, + versionInfoAttrs)...), ) if err != nil { log.Fatal(err) @@ -310,14 +315,15 @@ func InitWithSpanProcessorWrapper(cfg *config.AgentConfig, wrapper SpanProcessor } } -func createResources(serviceName string, resources map[string]string) []attribute.KeyValue { +func createResources(serviceName string, resources map[string]string, + versionInfo []attribute.KeyValue) []attribute.KeyValue { retValues := []attribute.KeyValue{ semconv.ServiceNameKey.String(serviceName), - semconv.TelemetrySDKNameKey.String("hypertrace"), - semconv.TelemetrySDKVersionKey.String(version.Version), semconv.TelemetrySDKLanguageGo, } + retValues = append(retValues, versionInfo...) + for k, v := range resources { retValues = append(retValues, attribute.String(k, v)) } @@ -326,13 +332,13 @@ func createResources(serviceName string, resources map[string]string) []attribut // RegisterService creates tracerprovider for a new service and returns a func which can be used to create spans and the TracerProvider func RegisterService(serviceName string, resourceAttributes map[string]string) (sdk.StartSpan, trace.TracerProvider, error) { - return RegisterServiceWithSpanProcessorWrapper(serviceName, resourceAttributes, nil) + return RegisterServiceWithSpanProcessorWrapper(serviceName, resourceAttributes, nil, versionInfoAttributes) } // RegisterServiceWithSpanProcessorWrapper creates a tracerprovider for a new service with a wrapper over opentelemetry span processor // and returns a func which can be used to create spans and the TracerProvider func RegisterServiceWithSpanProcessorWrapper(serviceName string, resourceAttributes map[string]string, - wrapper SpanProcessorWrapper) (sdk.StartSpan, trace.TracerProvider, error) { + wrapper SpanProcessorWrapper, versionInfoAttrs []attribute.KeyValue) (sdk.StartSpan, trace.TracerProvider, error) { mu.Lock() defer mu.Unlock() if !initialized { @@ -362,7 +368,7 @@ func RegisterServiceWithSpanProcessorWrapper(serviceName string, resourceAttribu resources, err := resource.New( context.Background(), - resource.WithAttributes(createResources(serviceName, resourceAttributes)...), + resource.WithAttributes(createResources(serviceName, resourceAttributes, versionInfoAttrs)...), ) if err != nil { log.Fatal(err) @@ -379,7 +385,7 @@ func RegisterServiceWithSpanProcessorWrapper(serviceName string, resourceAttribu }), tp, nil } -func initializeMetrics(cfg *config.AgentConfig) func() { +func initializeMetrics(cfg *config.AgentConfig, versionInfoAttrs []attribute.KeyValue) func() { if shouldDisableMetrics(cfg) { return func() {} } @@ -391,7 +397,7 @@ func initializeMetrics(cfg *config.AgentConfig) func() { } periodicReader := metric.NewPeriodicReader(metricsExporter) - resourceKvps := createResources(cfg.GetServiceName().GetValue(), cfg.ResourceAttributes) + resourceKvps := createResources(cfg.GetServiceName().GetValue(), cfg.ResourceAttributes, versionInfoAttrs) resourceKvps = append(resourceKvps, identifier.ServiceInstanceKeyValue) metricResources, err := resource.New(context.Background(), resource.WithAttributes(resourceKvps...)) if err != nil { diff --git a/instrumentation/opentelemetry/init_additional.go b/instrumentation/opentelemetry/init_additional.go index ed55b9b..838167e 100644 --- a/instrumentation/opentelemetry/init_additional.go +++ b/instrumentation/opentelemetry/init_additional.go @@ -34,7 +34,7 @@ func InitAsAdditional(cfg *config.AgentConfig) (trace.SpanProcessor, func()) { if cfg.GetServiceName().GetValue() != "" { resource, err := resource.New( context.Background(), - resource.WithAttributes(createResources(cfg.GetServiceName().GetValue(), cfg.ResourceAttributes)...), + resource.WithAttributes(createResources(cfg.GetServiceName().GetValue(), cfg.ResourceAttributes, versionInfoAttributes)...), ) if err != nil { log.Fatal(err) diff --git a/instrumentation/opentelemetry/init_test.go b/instrumentation/opentelemetry/init_test.go index 51a6ff2..cdbb194 100644 --- a/instrumentation/opentelemetry/init_test.go +++ b/instrumentation/opentelemetry/init_test.go @@ -365,7 +365,7 @@ func TestInitWithSpanProcessorWrapper(t *testing.T) { cfg.Reporting.Endpoint = config.String(srv.URL) wrapper := &mockSpanProcessorWrapper{} - shutdown := InitWithSpanProcessorWrapper(cfg, wrapper) + shutdown := InitWithSpanProcessorWrapper(cfg, wrapper, versionInfoAttributes) defer shutdown() // test wrapper is called for spans created by global trace provider @@ -380,7 +380,8 @@ func TestInitWithSpanProcessorWrapper(t *testing.T) { assert.Equal(t, 2, wrapper.onEndCount) // test wrapper is called for spans created by service trace provider - startSpan, _, err := RegisterServiceWithSpanProcessorWrapper("custom_service", map[string]string{"test1": "val1"}, wrapper) + startSpan, _, err := RegisterServiceWithSpanProcessorWrapper("custom_service", map[string]string{"test1": "val1"}, wrapper, + versionInfoAttributes) if err != nil { log.Fatalf("Error while initializing service: %v", err) }