Skip to content

Commit 0483033

Browse files
ymtdzzzdashpolepellaredMrAlias
authored
otelgrpc: Add Filter for stats handler (#5196)
* otelgrpc: Add filter for stats handler * Add entries to CHANGELOG * fix CHANGELOG * keep Deprecated comment of `WithInterceptorFilter` * deprecate `InterceptorFilter` type * change the location of `gctx.record` nil check location to reduce heap allocations * add documentation for filters and interceptor packages * fix the location of entries in CHANGELOG * more reasonable doc comment for interceptor package Co-authored-by: Robert Pająk <[email protected]> * more reasonable doc comment for interceptor package Co-authored-by: Robert Pająk <[email protected]> * Use more appropriate word in the comment of InterceptorFilter Co-authored-by: Robert Pająk <[email protected]> * more reasonable doc comment for filters package Co-authored-by: Robert Pająk <[email protected]> * fix the comment of `Filter` * Clearly describe the effects of the change * add tests for `stats_handler.go` --------- Co-authored-by: David Ashpole <[email protected]> Co-authored-by: Robert Pająk <[email protected]> Co-authored-by: Tyler Yahn <[email protected]>
1 parent d6e2fc4 commit 0483033

File tree

9 files changed

+819
-272
lines changed

9 files changed

+819
-272
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1515
- `prometheus` and `none` are supported values. You can specify multiple producers separated by a comma.
1616
- Add `WithFallbackMetricProducer` option that adds a fallback if the `OTEL_METRICS_PRODUCERS` is not set or empty.
1717
- The `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` module. This module provides a Baggage Span Processor. (#5404)
18+
- Add gRPC trace `Filter` for stats handler to `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`. (#5196)
19+
20+
### Changed
21+
22+
- The gRPC trace `Filter` for interceptor is renamed to `InterceptorFilter`. (#5196)
23+
- The gRPC trace filter functions `Any`, `All`, `None`, `Not`, `MethodName`, `MethodPrefix`, `FullMethodName`, `ServiceName`, `ServicePrefix` and `HealthCheck` for interceptor are moved to `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/filters/interceptor`.
24+
With this change, the filters in `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc` are now working for stats handler. (#5196)
25+
26+
### Deprecated
27+
28+
- The `InterceptorFilter` type in `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc` is deprecated. (#5196)
1829

1930
## [1.26.0/0.51.0/0.20.0/0.6.0/0.1.0] - 2024-04-24
2031

instrumentation/google.golang.org/grpc/otelgrpc/config.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
55

66
import (
7+
"google.golang.org/grpc/stats"
8+
79
"go.opentelemetry.io/otel"
810
"go.opentelemetry.io/otel/attribute"
911
"go.opentelemetry.io/otel/metric"
@@ -20,18 +22,26 @@ const (
2022
GRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code")
2123
)
2224

23-
// Filter is a predicate used to determine whether a given request in
24-
// interceptor info should be traced. A Filter must return true if
25+
// InterceptorFilter is a predicate used to determine whether a given request in
26+
// interceptor info should be instrumented. A InterceptorFilter must return true if
2527
// the request should be traced.
26-
type Filter func(*InterceptorInfo) bool
28+
//
29+
// Deprecated: Use stats handlers instead.
30+
type InterceptorFilter func(*InterceptorInfo) bool
31+
32+
// Filter is a predicate used to determine whether a given request in
33+
// should be instrumented by the attatched RPC tag info.
34+
// A Filter must return true if the request should be instrumented.
35+
type Filter func(*stats.RPCTagInfo) bool
2736

2837
// config is a group of options for this instrumentation.
2938
type config struct {
30-
Filter Filter
31-
Propagators propagation.TextMapPropagator
32-
TracerProvider trace.TracerProvider
33-
MeterProvider metric.MeterProvider
34-
SpanStartOptions []trace.SpanStartOption
39+
Filter Filter
40+
InterceptorFilter InterceptorFilter
41+
Propagators propagation.TextMapPropagator
42+
TracerProvider trace.TracerProvider
43+
MeterProvider metric.MeterProvider
44+
SpanStartOptions []trace.SpanStartOption
3545

3646
ReceivedEvent bool
3747
SentEvent bool
@@ -152,15 +162,30 @@ func (o tracerProviderOption) apply(c *config) {
152162
// WithInterceptorFilter returns an Option to use the request filter.
153163
//
154164
// Deprecated: Use stats handlers instead.
155-
func WithInterceptorFilter(f Filter) Option {
165+
func WithInterceptorFilter(f InterceptorFilter) Option {
156166
return interceptorFilterOption{f: f}
157167
}
158168

159169
type interceptorFilterOption struct {
160-
f Filter
170+
f InterceptorFilter
161171
}
162172

163173
func (o interceptorFilterOption) apply(c *config) {
174+
if o.f != nil {
175+
c.InterceptorFilter = o.f
176+
}
177+
}
178+
179+
// WithFilter returns an Option to use the request filter.
180+
func WithFilter(f Filter) Option {
181+
return filterOption{f: f}
182+
}
183+
184+
type filterOption struct {
185+
f Filter
186+
}
187+
188+
func (o filterOption) apply(c *config) {
164189
if o.f != nil {
165190
c.Filter = o.f
166191
}

instrumentation/google.golang.org/grpc/otelgrpc/filters/filters.go

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4+
// Package filters provides a set of filters useful with the
5+
// [otelgrpc.WithFilter] option to control which inbound requests are instrumented.
46
package filters // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/filters"
57

68
import (
79
"path"
810
"strings"
911

12+
"google.golang.org/grpc/stats"
13+
1014
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
1115
)
1216

@@ -19,20 +23,8 @@ type gRPCPath struct {
1923
// and returns as gRPCPath object that has divided service and method names
2024
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
2125
// If name is not FullMethod, returned gRPCPath has empty service field.
22-
func splitFullMethod(i *otelgrpc.InterceptorInfo) gRPCPath {
23-
var name string
24-
switch i.Type {
25-
case otelgrpc.UnaryServer:
26-
name = i.UnaryServerInfo.FullMethod
27-
case otelgrpc.StreamServer:
28-
name = i.StreamServerInfo.FullMethod
29-
case otelgrpc.UnaryClient, otelgrpc.StreamClient:
30-
name = i.Method
31-
default:
32-
name = i.Method
33-
}
34-
35-
s, m := path.Split(name)
26+
func splitFullMethod(i *stats.RPCTagInfo) gRPCPath {
27+
s, m := path.Split(i.FullMethodName)
3628
if s != "" {
3729
s = path.Clean(s)
3830
s = strings.TrimLeft(s, "/")
@@ -47,7 +39,7 @@ func splitFullMethod(i *otelgrpc.InterceptorInfo) gRPCPath {
4739
// Any takes a list of Filters and returns a Filter that
4840
// returns true if any Filter in the list returns true.
4941
func Any(fs ...otelgrpc.Filter) otelgrpc.Filter {
50-
return func(i *otelgrpc.InterceptorInfo) bool {
42+
return func(i *stats.RPCTagInfo) bool {
5143
for _, f := range fs {
5244
if f(i) {
5345
return true
@@ -60,7 +52,7 @@ func Any(fs ...otelgrpc.Filter) otelgrpc.Filter {
6052
// All takes a list of Filters and returns a Filter that
6153
// returns true only if all Filters in the list return true.
6254
func All(fs ...otelgrpc.Filter) otelgrpc.Filter {
63-
return func(i *otelgrpc.InterceptorInfo) bool {
55+
return func(i *stats.RPCTagInfo) bool {
6456
for _, f := range fs {
6557
if !f(i) {
6658
return false
@@ -78,15 +70,15 @@ func None(fs ...otelgrpc.Filter) otelgrpc.Filter {
7870

7971
// Not provides a convenience mechanism for inverting a Filter.
8072
func Not(f otelgrpc.Filter) otelgrpc.Filter {
81-
return func(i *otelgrpc.InterceptorInfo) bool {
73+
return func(i *stats.RPCTagInfo) bool {
8274
return !f(i)
8375
}
8476
}
8577

8678
// MethodName returns a Filter that returns true if the request's
8779
// method name matches the provided string n.
8880
func MethodName(n string) otelgrpc.Filter {
89-
return func(i *otelgrpc.InterceptorInfo) bool {
81+
return func(i *stats.RPCTagInfo) bool {
9082
p := splitFullMethod(i)
9183
return p.method == n
9284
}
@@ -95,7 +87,7 @@ func MethodName(n string) otelgrpc.Filter {
9587
// MethodPrefix returns a Filter that returns true if the request's
9688
// method starts with the provided string pre.
9789
func MethodPrefix(pre string) otelgrpc.Filter {
98-
return func(i *otelgrpc.InterceptorInfo) bool {
90+
return func(i *stats.RPCTagInfo) bool {
9991
p := splitFullMethod(i)
10092
return strings.HasPrefix(p.method, pre)
10193
}
@@ -105,26 +97,15 @@ func MethodPrefix(pre string) otelgrpc.Filter {
10597
// full RPC method string, i.e. /package.service/method, starts with
10698
// the provided string n.
10799
func FullMethodName(n string) otelgrpc.Filter {
108-
return func(i *otelgrpc.InterceptorInfo) bool {
109-
var fm string
110-
switch i.Type {
111-
case otelgrpc.UnaryClient, otelgrpc.StreamClient:
112-
fm = i.Method
113-
case otelgrpc.UnaryServer:
114-
fm = i.UnaryServerInfo.FullMethod
115-
case otelgrpc.StreamServer:
116-
fm = i.StreamServerInfo.FullMethod
117-
default:
118-
fm = i.Method
119-
}
120-
return fm == n
100+
return func(i *stats.RPCTagInfo) bool {
101+
return i.FullMethodName == n
121102
}
122103
}
123104

124105
// ServiceName returns a Filter that returns true if the request's
125106
// service name, i.e. package.service, matches s.
126107
func ServiceName(s string) otelgrpc.Filter {
127-
return func(i *otelgrpc.InterceptorInfo) bool {
108+
return func(i *stats.RPCTagInfo) bool {
128109
p := splitFullMethod(i)
129110
return p.service == s
130111
}
@@ -133,7 +114,7 @@ func ServiceName(s string) otelgrpc.Filter {
133114
// ServicePrefix returns a Filter that returns true if the request's
134115
// service name, i.e. package.service, starts with the provided string pre.
135116
func ServicePrefix(pre string) otelgrpc.Filter {
136-
return func(i *otelgrpc.InterceptorInfo) bool {
117+
return func(i *stats.RPCTagInfo) bool {
137118
p := splitFullMethod(i)
138119
return strings.HasPrefix(p.service, pre)
139120
}

0 commit comments

Comments
 (0)