Skip to content

Commit

Permalink
otelgrpc: Remove high cardinality metric attributes (#4322)
Browse files Browse the repository at this point in the history
  • Loading branch information
MadVikingGod committed Nov 6, 2023
1 parent 2a5fe23 commit b44dfc9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 47 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -46,6 +46,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Upgrade dependencies of OpenTelemetry Go to use the new [`v1.19.0`/`v0.42.0`/`v0.0.7` release](https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0).
- Use `grpc.StatsHandler` for gRPC instrumentation in `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/example`. (#4325)

### Removed

- The `net.sock.peer.*` and `net.peer.*` high cardinality attributes are removed from the metrics generated by `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`. (#4322)

## [1.19.0/0.44.0/0.13.0] - 2023-09-12

### Added
Expand Down
27 changes: 14 additions & 13 deletions instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go
Expand Up @@ -83,7 +83,7 @@ func UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor {
return invoker(ctx, method, req, reply, cc, callOpts...)
}

name, attr := spanInfo(method, cc.Target())
name, attr, _ := telemetryAttributes(method, cc.Target())

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindClient),
Expand Down Expand Up @@ -277,7 +277,7 @@ func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor {
return streamer(ctx, desc, cc, method, callOpts...)
}

name, attr := spanInfo(method, cc.Target())
name, attr, _ := telemetryAttributes(method, cc.Target())

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindClient),
Expand Down Expand Up @@ -346,7 +346,7 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
}

ctx = extract(ctx, cfg.Propagators)
name, attr := spanInfo(info.FullMethod, peerFromCtx(ctx))
name, attr, metricAttrs := telemetryAttributes(info.FullMethod, peerFromCtx(ctx))

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindServer),
Expand Down Expand Up @@ -386,8 +386,8 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
span.SetAttributes(grpcStatusCodeAttr)

elapsedTime := time.Since(before).Milliseconds()
attr = append(attr, grpcStatusCodeAttr)
cfg.rpcDuration.Record(ctx, float64(elapsedTime), metric.WithAttributes(attr...))
metricAttrs = append(metricAttrs, grpcStatusCodeAttr)
cfg.rpcDuration.Record(ctx, float64(elapsedTime), metric.WithAttributes(metricAttrs...))

return resp, err
}
Expand Down Expand Up @@ -468,7 +468,7 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
}

ctx = extract(ctx, cfg.Propagators)
name, attr := spanInfo(info.FullMethod, peerFromCtx(ctx))
name, attr, _ := telemetryAttributes(info.FullMethod, peerFromCtx(ctx))

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindServer),
Expand Down Expand Up @@ -498,17 +498,18 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
}
}

// spanInfo returns a span name and all appropriate attributes from the gRPC
// method and peer address.
func spanInfo(fullMethod, peerAddress string) (string, []attribute.KeyValue) {
name, mAttrs := internal.ParseFullMethod(fullMethod)
// telemetryAttributes returns a span name and span and metric attributes from
// the gRPC method and peer address.
func telemetryAttributes(fullMethod, peerAddress string) (string, []attribute.KeyValue, []attribute.KeyValue) {
name, methodAttrs := internal.ParseFullMethod(fullMethod)
peerAttrs := peerAttr(peerAddress)

attrs := make([]attribute.KeyValue, 0, 1+len(mAttrs)+len(peerAttrs))
attrs := make([]attribute.KeyValue, 0, 1+len(methodAttrs)+len(peerAttrs))
attrs = append(attrs, RPCSystemGRPC)
attrs = append(attrs, mAttrs...)
attrs = append(attrs, methodAttrs...)
metricAttrs := attrs[:1+len(methodAttrs)]
attrs = append(attrs, peerAttrs...)
return name, attrs
return name, attrs, metricAttrs
}

// peerAttr returns attributes about the peer address.
Expand Down
34 changes: 0 additions & 34 deletions instrumentation/google.golang.org/grpc/otelgrpc/test/grpc_test.go
Expand Up @@ -16,7 +16,6 @@ package test

import (
"context"
"fmt"
"net"
"strconv"
"testing"
Expand Down Expand Up @@ -665,12 +664,6 @@ func checkUnaryServerRecords(t *testing.T, reader metric.Reader) {
assert.NoError(t, err)
require.Len(t, rm.ScopeMetrics, 1)

// TODO: Remove these #4322
address, ok := findScopeMetricAttribute(rm.ScopeMetrics[0], semconv.NetSockPeerAddrKey)
assert.True(t, ok)
port, ok := findScopeMetricAttribute(rm.ScopeMetrics[0], semconv.NetSockPeerPortKey)
assert.True(t, ok)

want := metricdata.ScopeMetrics{
Scope: wantInstrumentationScope,
Metrics: []metricdata.Metrics{
Expand All @@ -687,8 +680,6 @@ func checkUnaryServerRecords(t *testing.T, reader metric.Reader) {
semconv.RPCService("grpc.testing.TestService"),
otelgrpc.RPCSystemGRPC,
otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)),
address,
port,
),
},
{
Expand All @@ -697,8 +688,6 @@ func checkUnaryServerRecords(t *testing.T, reader metric.Reader) {
semconv.RPCService("grpc.testing.TestService"),
otelgrpc.RPCSystemGRPC,
otelgrpc.GRPCStatusCodeKey.Int64(int64(codes.OK)),
address,
port,
),
},
},
Expand All @@ -718,26 +707,3 @@ func findAttribute(kvs []attribute.KeyValue, key attribute.Key) (attribute.KeyVa
}
return attribute.KeyValue{}, false
}

func findScopeMetricAttribute(sm metricdata.ScopeMetrics, key attribute.Key) (attribute.KeyValue, bool) {
for _, m := range sm.Metrics {
// This only needs to cover data types used by the instrumentation.
switch d := m.Data.(type) {
case metricdata.Histogram[int64]:
for _, dp := range d.DataPoints {
if kv, ok := findAttribute(dp.Attributes.ToSlice(), key); ok {
return kv, true
}
}
case metricdata.Histogram[float64]:
for _, dp := range d.DataPoints {
if kv, ok := findAttribute(dp.Attributes.ToSlice(), key); ok {
return kv, true
}
}
default:
panic(fmt.Sprintf("unexpected data type %T - name %s", d, m.Name))
}
}
return attribute.KeyValue{}, false
}

0 comments on commit b44dfc9

Please sign in to comment.