diff --git a/pkg/internal/export/attributes/attr_defs.go b/pkg/internal/export/attributes/attr_defs.go index 5779056c5..f97ead734 100644 --- a/pkg/internal/export/attributes/attr_defs.go +++ b/pkg/internal/export/attributes/attr_defs.go @@ -44,10 +44,18 @@ func getDefinitions(groups AttrGroups) map[Section]AttrReportGroup { Disabled: !promEnabled, Attributes: map[attr.Name]Default{ attr.TargetInstance: true, - attr.ServiceName: true, attr.ServiceNamespace: true, }, } + // ServiceName is reported both as resource and metrics attribute, as + // the OTEL definition requires that it is reported as resource attribute + // but Grafana Cloud takes int from the metric + var appAttributes = AttrReportGroup{ + SubGroups: []*AttrReportGroup{&prometheusAttributes}, + Attributes: map[attr.Name]Default{ + attr.ServiceName: true, + }, + } // attributes to be reported exclusively for network metrics when // kubernetes metadata is enabled @@ -159,19 +167,19 @@ func getDefinitions(groups AttrGroups) map[Section]AttrReportGroup { }, }, HTTPServerDuration.Section: { - SubGroups: []*AttrReportGroup{&prometheusAttributes, &appKubeAttributes, &httpCommon, &serverInfo}, + SubGroups: []*AttrReportGroup{&appAttributes, &appKubeAttributes, &httpCommon, &serverInfo}, }, HTTPServerRequestSize.Section: { - SubGroups: []*AttrReportGroup{&prometheusAttributes, &appKubeAttributes, &httpCommon, &serverInfo}, + SubGroups: []*AttrReportGroup{&appAttributes, &appKubeAttributes, &httpCommon, &serverInfo}, }, HTTPClientDuration.Section: { - SubGroups: []*AttrReportGroup{&prometheusAttributes, &appKubeAttributes, &httpCommon, &httpClientInfo}, + SubGroups: []*AttrReportGroup{&appAttributes, &appKubeAttributes, &httpCommon, &httpClientInfo}, }, HTTPClientRequestSize.Section: { - SubGroups: []*AttrReportGroup{&prometheusAttributes, &appKubeAttributes, &httpCommon, &httpClientInfo}, + SubGroups: []*AttrReportGroup{&appAttributes, &appKubeAttributes, &httpCommon, &httpClientInfo}, }, RPCClientDuration.Section: { - SubGroups: []*AttrReportGroup{&prometheusAttributes, &appKubeAttributes, &grpcClientInfo}, + SubGroups: []*AttrReportGroup{&appAttributes, &appKubeAttributes, &grpcClientInfo}, Attributes: map[attr.Name]Default{ attr.RPCMethod: true, attr.RPCSystem: true, @@ -179,7 +187,7 @@ func getDefinitions(groups AttrGroups) map[Section]AttrReportGroup { }, }, RPCServerDuration.Section: { - SubGroups: []*AttrReportGroup{&prometheusAttributes, &appKubeAttributes, &serverInfo}, + SubGroups: []*AttrReportGroup{&appAttributes, &appKubeAttributes, &serverInfo}, Attributes: map[attr.Name]Default{ attr.RPCMethod: true, attr.RPCSystem: true, @@ -190,7 +198,7 @@ func getDefinitions(groups AttrGroups) map[Section]AttrReportGroup { }, }, SQLClientDuration.Section: { - SubGroups: []*AttrReportGroup{&prometheusAttributes, &appKubeAttributes}, + SubGroups: []*AttrReportGroup{&appAttributes, &appKubeAttributes}, Attributes: map[attr.Name]Default{ attr.DBOperation: true, }, diff --git a/pkg/internal/pipe/instrumenter_test.go b/pkg/internal/pipe/instrumenter_test.go index c2aded4ad..304a38d4a 100644 --- a/pkg/internal/pipe/instrumenter_test.go +++ b/pkg/internal/pipe/instrumenter_test.go @@ -92,6 +92,7 @@ func TestBasicPipeline(t *testing.T) { string(attr.HTTPResponseStatusCode): "404", string(attr.HTTPUrlPath): "/foo/bar", string(attr.ClientAddr): "1.1.1.1", + string(semconv.ServiceNameKey): "foo-svc", }, ResourceAttributes: map[string]string{ string(semconv.ServiceNameKey): "foo-svc", @@ -281,6 +282,7 @@ func TestRouteConsolidation(t *testing.T) { Name: "http.server.request.duration", Unit: "s", Attributes: map[string]string{ + string(semconv.ServiceNameKey): "svc-1", string(attr.HTTPRequestMethod): "GET", string(attr.HTTPResponseStatusCode): "200", string(semconv.HTTPRouteKey): "/user/{id}", @@ -297,6 +299,7 @@ func TestRouteConsolidation(t *testing.T) { Name: "http.server.request.duration", Unit: "s", Attributes: map[string]string{ + string(semconv.ServiceNameKey): "svc-1", string(attr.HTTPRequestMethod): "GET", string(attr.HTTPResponseStatusCode): "200", string(semconv.HTTPRouteKey): "/products/{id}/push", @@ -313,6 +316,7 @@ func TestRouteConsolidation(t *testing.T) { Name: "http.server.request.duration", Unit: "s", Attributes: map[string]string{ + string(semconv.ServiceNameKey): "svc-1", string(attr.HTTPRequestMethod): "GET", string(attr.HTTPResponseStatusCode): "200", string(semconv.HTTPRouteKey): "/**", @@ -361,6 +365,7 @@ func TestGRPCPipeline(t *testing.T) { Name: "rpc.server.duration", Unit: "s", Attributes: map[string]string{ + string(semconv.ServiceNameKey): "grpc-svc", string(semconv.RPCSystemKey): "grpc", string(semconv.RPCGRPCStatusCodeKey): "3", string(semconv.RPCMethodKey): "/foo/bar", @@ -443,6 +448,7 @@ func TestBasicPipelineInfo(t *testing.T) { string(attr.HTTPResponseStatusCode): "204", string(attr.HTTPUrlPath): "/aaa/bbb", string(attr.ClientAddr): "1.1.1.1", + string(semconv.ServiceNameKey): "comm", }, ResourceAttributes: map[string]string{ string(semconv.ServiceNameKey): "comm", @@ -523,12 +529,14 @@ func TestSpanAttributeFilterNode(t *testing.T) { assert.Equal(t, map[string]map[string]string{ "/user/1234": { + string(semconv.ServiceNameKey): "svc-1", string(attr.ClientAddr): "1.1.1.1", string(attr.HTTPRequestMethod): "GET", string(attr.HTTPResponseStatusCode): "201", string(attr.HTTPUrlPath): "/user/1234", }, "/user/4321": { + string(semconv.ServiceNameKey): "svc-3", string(attr.ClientAddr): "1.1.1.1", string(attr.HTTPRequestMethod): "GET", string(attr.HTTPResponseStatusCode): "203", diff --git a/pkg/internal/request/span_getters.go b/pkg/internal/request/span_getters.go index 89be6d9ea..53ae5f44c 100644 --- a/pkg/internal/request/span_getters.go +++ b/pkg/internal/request/span_getters.go @@ -12,6 +12,7 @@ import ( // SpanOTELGetters returns the attributes.Getter function that returns the // OTEL attribute.KeyValue of a given attribute name. +// nolint:cyclop func SpanOTELGetters(name attr.Name) (attributes.Getter[*Span, attribute.KeyValue], bool) { var getter attributes.Getter[*Span, attribute.KeyValue] switch name { @@ -35,6 +36,8 @@ func SpanOTELGetters(name attr.Name) (attributes.Getter[*Span, attribute.KeyValu getter = func(_ *Span) attribute.KeyValue { return semconv.RPCSystemGRPC } case attr.RPCGRPCStatusCode: getter = func(s *Span) attribute.KeyValue { return semconv.RPCGRPCStatusCodeKey.Int(s.Status) } + case attr.ServiceName: + getter = func(s *Span) attribute.KeyValue { return semconv.ServiceName(s.ServiceID.Name) } case attr.DBOperation: getter = func(span *Span) attribute.KeyValue { return semconv.DBOperation(span.Method) } }