From a6b8d672fabd7f2af99ccabb543e895e9d140c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1igo=20Horcajo?= Date: Mon, 12 Feb 2024 12:11:06 +0100 Subject: [PATCH] otelgrpc: add custom attributes to the stats handler Fixes https://github.com/open-telemetry/opentelemetry-go-contrib/issues/3894 --- .../google.golang.org/grpc/otelgrpc/config.go | 14 ++ .../grpc/otelgrpc/stats_handler.go | 6 + .../otelgrpc/test/grpc_stats_handler_test.go | 168 ++++++++++++------ .../grpc/otelgrpc/test/stats_handler_test.go | 4 + 4 files changed, 140 insertions(+), 52 deletions(-) diff --git a/instrumentation/google.golang.org/grpc/otelgrpc/config.go b/instrumentation/google.golang.org/grpc/otelgrpc/config.go index ab091cf6ade..e01703d3691 100644 --- a/instrumentation/google.golang.org/grpc/otelgrpc/config.go +++ b/instrumentation/google.golang.org/grpc/otelgrpc/config.go @@ -42,6 +42,7 @@ type config struct { TracerProvider trace.TracerProvider MeterProvider metric.MeterProvider SpanStartOptions []trace.SpanStartOption + Attributes []attribute.KeyValue ReceivedEvent bool SentEvent bool @@ -257,3 +258,16 @@ func (o spanStartOption) apply(c *config) { func WithSpanOptions(opts ...trace.SpanStartOption) Option { return spanStartOption{opts} } + +type attributesOption struct{ a []attribute.KeyValue } + +func (o attributesOption) apply(c *config) { + if o.a != nil { + c.Attributes = o.a + } +} + +// WithAttributes returns an Option to add custom attributes to the spans and metrics. +func WithAttributes(a ...attribute.KeyValue) Option { + return attributesOption{a: a} +} diff --git a/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go b/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go index 201867a8694..37ddf676c3a 100644 --- a/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go +++ b/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go @@ -58,6 +58,9 @@ func (h *serverHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont name, attrs := internal.ParseFullMethod(info.FullMethodName) attrs = append(attrs, RPCSystemGRPC) + + attrs = append(attrs, h.config.Attributes...) + ctx, _ = h.tracer.Start( trace.ContextWithRemoteSpanContext(ctx, trace.SpanContextFromContext(ctx)), name, @@ -98,6 +101,9 @@ func NewClientHandler(opts ...Option) stats.Handler { func (h *clientHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context { name, attrs := internal.ParseFullMethod(info.FullMethodName) attrs = append(attrs, RPCSystemGRPC) + + attrs = append(attrs, h.config.Attributes...) + ctx, _ = h.tracer.Start( ctx, name, diff --git a/instrumentation/google.golang.org/grpc/otelgrpc/test/grpc_stats_handler_test.go b/instrumentation/google.golang.org/grpc/otelgrpc/test/grpc_stats_handler_test.go index 72f9de68758..53f3f5e6399 100644 --- a/instrumentation/google.golang.org/grpc/otelgrpc/test/grpc_stats_handler_test.go +++ b/instrumentation/google.golang.org/grpc/otelgrpc/test/grpc_stats_handler_test.go @@ -33,6 +33,8 @@ import ( testpb "google.golang.org/grpc/interop/grpc_testing" ) +var testAttr = attribute.String("test", "OK") + func TestStatsHandler(t *testing.T) { tests := []struct { name string @@ -71,7 +73,8 @@ func TestStatsHandler(t *testing.T) { otelgrpc.WithTracerProvider(clientTP), otelgrpc.WithMeterProvider(clientMP), otelgrpc.WithMessageEvents(otelgrpc.ReceivedEvents, otelgrpc.SentEvents), - otelgrpc.WithFilter(filters.ServiceName(tt.filterSvcName))), + otelgrpc.WithFilter(filters.ServiceName(tt.filterSvcName)), + otelgrpc.WithAttributes(testAttr)), ), }, []grpc.ServerOption{ @@ -79,7 +82,8 @@ func TestStatsHandler(t *testing.T) { otelgrpc.WithTracerProvider(serverTP), otelgrpc.WithMeterProvider(serverMP), otelgrpc.WithMessageEvents(otelgrpc.ReceivedEvents, otelgrpc.SentEvents), - otelgrpc.WithFilter(filters.ServiceName(tt.filterSvcName))), + otelgrpc.WithFilter(filters.ServiceName(tt.filterSvcName)), + otelgrpc.WithAttributes(testAttr)), ), }, ) @@ -168,6 +172,7 @@ func checkClientSpans(t *testing.T, spans []trace.ReadOnlySpan, addr string) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr(host), semconv.NetSockPeerPort(port), + testAttr, }, emptySpan.Attributes()) largeSpan := spans[1] @@ -200,6 +205,7 @@ func checkClientSpans(t *testing.T, spans []trace.ReadOnlySpan, addr string) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr(host), semconv.NetSockPeerPort(port), + testAttr, }, largeSpan.Attributes()) streamInput := spans[2] @@ -260,6 +266,7 @@ func checkClientSpans(t *testing.T, spans []trace.ReadOnlySpan, addr string) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr(host), semconv.NetSockPeerPort(port), + testAttr, }, streamInput.Attributes()) streamOutput := spans[3] @@ -319,6 +326,7 @@ func checkClientSpans(t *testing.T, spans []trace.ReadOnlySpan, addr string) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr(host), semconv.NetSockPeerPort(port), + testAttr, }, streamOutput.Attributes()) pingPong := spans[4] @@ -405,6 +413,7 @@ func checkClientSpans(t *testing.T, spans []trace.ReadOnlySpan, addr string) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr(host), semconv.NetSockPeerPort(port), + testAttr, }, pingPong.Attributes()) } @@ -443,6 +452,7 @@ func checkServerSpans(t *testing.T, spans []trace.ReadOnlySpan) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr("127.0.0.1"), port, + testAttr, }, emptySpan.Attributes()) largeSpan := spans[1] @@ -477,6 +487,7 @@ func checkServerSpans(t *testing.T, spans []trace.ReadOnlySpan) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr("127.0.0.1"), port, + testAttr, }, largeSpan.Attributes()) streamInput := spans[2] @@ -539,6 +550,7 @@ func checkServerSpans(t *testing.T, spans []trace.ReadOnlySpan) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr("127.0.0.1"), port, + testAttr, }, streamInput.Attributes()) streamOutput := spans[3] @@ -600,6 +612,7 @@ func checkServerSpans(t *testing.T, spans []trace.ReadOnlySpan) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr("127.0.0.1"), port, + testAttr, }, streamOutput.Attributes()) pingPong := spans[4] @@ -688,6 +701,7 @@ func checkServerSpans(t *testing.T, spans []trace.ReadOnlySpan) { otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)), semconv.NetSockPeerAddr("127.0.0.1"), port, + testAttr, }, pingPong.Attributes()) } @@ -716,35 +730,40 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, }, }, @@ -760,7 +779,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(0)), @@ -772,7 +792,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, Max: metricdata.NewExtrema(int64(314167)), @@ -784,7 +805,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -796,7 +818,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2}, Max: metricdata.NewExtrema(int64(58987)), @@ -808,7 +831,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2}, Max: metricdata.NewExtrema(int64(58987)), @@ -830,7 +854,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(0)), @@ -842,7 +867,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, Max: metricdata.NewExtrema(int64(271840)), @@ -854,7 +880,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2}, Max: metricdata.NewExtrema(int64(45912)), @@ -866,7 +893,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(21)), @@ -878,7 +906,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2}, Max: metricdata.NewExtrema(int64(45918)), @@ -901,7 +930,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -914,7 +944,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -927,7 +958,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -940,7 +972,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -953,7 +986,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -976,7 +1010,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -989,7 +1024,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1002,7 +1038,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -1015,7 +1052,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1028,7 +1066,8 @@ func checkClientMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -1069,35 +1108,40 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, { Attributes: attribute.NewSet( semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), }, }, }, @@ -1113,7 +1157,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(0)), @@ -1125,7 +1170,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, Max: metricdata.NewExtrema(int64(271840)), @@ -1137,7 +1183,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2}, Max: metricdata.NewExtrema(int64(45912)), @@ -1149,7 +1196,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(21)), @@ -1161,7 +1209,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2}, Max: metricdata.NewExtrema(int64(45918)), @@ -1183,7 +1232,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(0)), @@ -1195,7 +1245,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, Max: metricdata.NewExtrema(int64(314167)), @@ -1207,7 +1258,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -1219,7 +1271,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2}, Max: metricdata.NewExtrema(int64(58987)), @@ -1231,7 +1284,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { Attributes: attribute.NewSet( semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2}, Max: metricdata.NewExtrema(int64(58987)), @@ -1254,7 +1308,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1267,7 +1322,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1280,7 +1336,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -1293,7 +1350,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1306,7 +1364,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -1329,7 +1388,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("EmptyCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1342,7 +1402,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("UnaryCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1355,7 +1416,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingInputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(1)), @@ -1368,7 +1430,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("StreamingOutputCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), @@ -1381,7 +1444,8 @@ func checkServerMetrics(t *testing.T, reader metric.Reader) { semconv.RPCGRPCStatusCodeOk, semconv.RPCMethod("FullDuplexCall"), semconv.RPCService("grpc.testing.TestService"), - semconv.RPCSystemGRPC), + semconv.RPCSystemGRPC, + testAttr), Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Max: metricdata.NewExtrema(int64(4)), diff --git a/instrumentation/google.golang.org/grpc/otelgrpc/test/stats_handler_test.go b/instrumentation/google.golang.org/grpc/otelgrpc/test/stats_handler_test.go index be2d0c2472a..8a2eb974161 100644 --- a/instrumentation/google.golang.org/grpc/otelgrpc/test/stats_handler_test.go +++ b/instrumentation/google.golang.org/grpc/otelgrpc/test/stats_handler_test.go @@ -36,6 +36,7 @@ func TestStatsHandlerHandleRPCServerErrors(t *testing.T) { serverHandler := otelgrpc.NewServerHandler( otelgrpc.WithTracerProvider(tp), otelgrpc.WithMeterProvider(mp), + otelgrpc.WithAttributes(testAttr), ) serviceName := "TestGrpcService" @@ -79,6 +80,7 @@ func assertStatsHandlerServerMetrics(t *testing.T, reader metric.Reader, service semconv.RPCService(serviceName), otelgrpc.RPCSystemGRPC, otelgrpc.GRPCStatusCodeKey.Int64(int64(code)), + testAttr, ), }, }, @@ -97,6 +99,7 @@ func assertStatsHandlerServerMetrics(t *testing.T, reader metric.Reader, service semconv.RPCService(serviceName), otelgrpc.RPCSystemGRPC, otelgrpc.GRPCStatusCodeKey.Int64(int64(code)), + testAttr, ), }, }, @@ -115,6 +118,7 @@ func assertStatsHandlerServerMetrics(t *testing.T, reader metric.Reader, service semconv.RPCService(serviceName), otelgrpc.RPCSystemGRPC, otelgrpc.GRPCStatusCodeKey.Int64(int64(code)), + testAttr, ), }, },