diff --git a/internal/test/integration/red_test.go b/internal/test/integration/red_test.go index 4bc950ab94..9a8d47b9df 100644 --- a/internal/test/integration/red_test.go +++ b/internal/test/integration/red_test.go @@ -128,7 +128,8 @@ func testSpanMetricsForHTTPLibraryOTelFormat(t *testing.T, svcName, svcNs string `status_code="STATUS_CODE_UNSET",` + // 404 is OK for server spans `service_namespace="` + svcNs + `",` + `service_name="` + svcName + `",` + - `span_name="GET /basic/:rnd"` + + `span_name="GET /basic/:rnd",` + + `telemetry_sdk_language="go"` + `}`) require.NoError(t, err) // check span metric latency exists @@ -180,7 +181,8 @@ func testSpanMetricsForHTTPLibrary(t *testing.T, svcName, svcNs string) { `status_code="STATUS_CODE_UNSET",` + // 404 is OK for server spans `service_namespace="` + svcNs + `",` + `service_name="` + svcName + `",` + - `span_name="GET /basic/:rnd"` + + `span_name="GET /basic/:rnd",` + + `telemetry_sdk_language="go"` + `}`) require.NoError(t, err) // check span metric latency exists diff --git a/pkg/appolly/app/request/span_getters.go b/pkg/appolly/app/request/span_getters.go index 465269ed63..0bafc0b0cd 100644 --- a/pkg/appolly/app/request/span_getters.go +++ b/pkg/appolly/app/request/span_getters.go @@ -91,6 +91,10 @@ func spanOTELGetters(name attr.Name) (attributes.Getter[*Span, attribute.KeyValu getter = func(s *Span) attribute.KeyValue { return SpanNameMetric(s.TraceName()) } case attr.Source: getter = func(_ *Span) attribute.KeyValue { return SourceMetric(attr.VendorPrefix) } + case attr.TelemetrySDKLanguage: + getter = func(s *Span) attribute.KeyValue { + return semconv.TelemetrySDKLanguageKey.String(s.Service.SDKLanguage.String()) + } case attr.StatusCode: getter = func(s *Span) attribute.KeyValue { return StatusCodeMetric(SpanStatusCode(s)) } case attr.DBOperation: diff --git a/pkg/export/attributes/attr_defs.go b/pkg/export/attributes/attr_defs.go index b5c1d72f7e..c68eb13790 100644 --- a/pkg/export/attributes/attr_defs.go +++ b/pkg/export/attributes/attr_defs.go @@ -337,17 +337,18 @@ func getDefinitions( // TODO: when service graph and span metrics implement attribute selection, replace this section by proper metric names "---- temporary placeholder for span and service graph metrics ----": { Attributes: map[attr.Name]Default{ - attr.Client: false, - attr.ClientNamespace: false, - attr.Server: false, - attr.ServerNamespace: false, - attr.Source: false, - attr.ServiceName: false, - attr.ServiceInstanceID: false, - attr.ServiceNamespace: false, - attr.SpanKind: false, - attr.SpanName: false, - attr.StatusCode: false, + attr.Client: false, + attr.ClientNamespace: false, + attr.Server: false, + attr.ServerNamespace: false, + attr.Source: false, + attr.ServiceName: false, + attr.ServiceInstanceID: false, + attr.ServiceNamespace: false, + attr.SpanKind: false, + attr.SpanName: false, + attr.StatusCode: false, + attr.TelemetrySDKLanguage: false, }, }, } diff --git a/pkg/export/attributes/names/attrs.go b/pkg/export/attributes/names/attrs.go index e057d503c0..b77d06b062 100644 --- a/pkg/export/attributes/names/attrs.go +++ b/pkg/export/attributes/names/attrs.go @@ -63,6 +63,7 @@ const ( GraphQLOperationType = Name(semconv.GraphqlOperationTypeKey) DNSAnswers = Name("dns.answers") ErrorMessage = Name("error.message") + TelemetrySDKLanguage = Name(semconv.TelemetrySDKLanguageKey) K8sNamespaceName = Name("k8s.namespace.name") K8sPodName = Name("k8s.pod.name") diff --git a/pkg/export/otel/metrics.go b/pkg/export/otel/metrics.go index abfa22d7a6..b614d50543 100644 --- a/pkg/export/otel/metrics.go +++ b/pkg/export/otel/metrics.go @@ -789,6 +789,7 @@ func (mr *MetricsReporter) spanMetricAttributes() []attributes.Field[*request.Sp attr.SpanName, attr.StatusCode, attr.Source, + attr.TelemetrySDKLanguage, }), // hostID is not taken from the span but common to the metrics reporter, // so the getter is injected here directly diff --git a/pkg/export/prom/prom.go b/pkg/export/prom/prom.go index 2307346649..458f25f5f7 100644 --- a/pkg/export/prom/prom.go +++ b/pkg/export/prom/prom.go @@ -1037,7 +1037,7 @@ func appendK8sLabelValuesService(values []string, service *svc.Attrs) []string { } func labelNamesSpans() []string { - return []string{serviceNameKey, serviceNamespaceKey, spanNameKey, statusCodeKey, spanKindKey, serviceInstanceKey, serviceJobKey, sourceKey} + return []string{serviceNameKey, serviceNamespaceKey, spanNameKey, statusCodeKey, spanKindKey, serviceInstanceKey, serviceJobKey, sourceKey, telemetryLanguageKey} } func (r *metricsReporter) labelValuesSpans(span *request.Span) []string { @@ -1050,6 +1050,7 @@ func (r *metricsReporter) labelValuesSpans(span *request.Span) []string { span.Service.UID.Instance, // app instance ID span.Service.Job(), attr.VendorPrefix, + span.Service.SDKLanguage.String(), } }