diff --git a/CHANGELOG.md b/CHANGELOG.md index f6ae2ffb08c..454981dbbd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Support for stdoutlog exporter in `go.opentelemetry.io/contrib/config`. (#5850) - Add macOS ARM64 platform to the compatibility testing suite. (#5868) +- Add custom attributes to the stats handler in `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`. (#5133) ### Removed 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 7d951d6b2a3..ad535dffcfc 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 @@ -34,6 +34,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 @@ -72,7 +74,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{ @@ -80,7 +83,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)), ), }, ) @@ -169,6 +173,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] @@ -201,6 +206,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] @@ -261,6 +267,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] @@ -320,6 +327,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] @@ -406,6 +414,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()) } @@ -444,6 +453,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] @@ -478,6 +488,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] @@ -540,6 +551,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] @@ -601,6 +613,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] @@ -689,6 +702,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()) } @@ -717,35 +731,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), }, }, }, @@ -761,7 +780,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)), @@ -773,7 +793,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)), @@ -785,7 +806,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)), @@ -797,7 +819,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)), @@ -809,7 +832,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)), @@ -831,7 +855,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)), @@ -843,7 +868,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)), @@ -855,7 +881,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)), @@ -867,7 +894,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)), @@ -879,7 +907,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)), @@ -902,7 +931,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)), @@ -915,7 +945,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)), @@ -928,7 +959,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)), @@ -941,7 +973,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)), @@ -954,7 +987,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)), @@ -977,7 +1011,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)), @@ -990,7 +1025,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)), @@ -1003,7 +1039,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)), @@ -1016,7 +1053,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)), @@ -1029,7 +1067,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)), @@ -1070,35 +1109,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), }, }, }, @@ -1114,7 +1158,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)), @@ -1126,7 +1171,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)), @@ -1138,7 +1184,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)), @@ -1150,7 +1197,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)), @@ -1162,7 +1210,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)), @@ -1184,7 +1233,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)), @@ -1196,7 +1246,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)), @@ -1208,7 +1259,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)), @@ -1220,7 +1272,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)), @@ -1232,7 +1285,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)), @@ -1255,7 +1309,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)), @@ -1268,7 +1323,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)), @@ -1281,7 +1337,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)), @@ -1294,7 +1351,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)), @@ -1307,7 +1365,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)), @@ -1330,7 +1389,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)), @@ -1343,7 +1403,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)), @@ -1356,7 +1417,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)), @@ -1369,7 +1431,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)), @@ -1382,7 +1445,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, ), }, },