Skip to content

Commit 26a5ffa

Browse files
authored
When client or server is empty, set it to "unresolved" (#585)
* Replace IPFilter by UnresolvedHostRenamer * Fix metalinter in non-linux * extra debug * move replacement to getters * Fix tests
1 parent bf56e73 commit 26a5ffa

23 files changed

+579
-535
lines changed

pkg/app/request/span_getters.go

Lines changed: 9 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,18 @@
44
package request
55

66
import (
7-
"strconv"
8-
97
"go.opentelemetry.io/otel/attribute"
108
semconv "go.opentelemetry.io/otel/semconv/v1.19.0"
119

1210
"go.opentelemetry.io/obi/pkg/export/attributes"
1311
attr "go.opentelemetry.io/obi/pkg/export/attributes/names"
1412
)
1513

16-
// SpanOTELGetters returns the attributes.Getter function that returns the
14+
// spanOTELGetters returns the attributes.Getter function that returns the
1715
// OTEL attribute.KeyValue of a given attribute name.
1816
//
1917
//nolint:cyclop
20-
func SpanOTELGetters(name attr.Name) (attributes.Getter[*Span, attribute.KeyValue], bool) {
18+
func spanOTELGetters(name attr.Name) (attributes.Getter[*Span, attribute.KeyValue], bool) {
2119
var getter attributes.Getter[*Span, attribute.KeyValue]
2220
switch name {
2321
case attr.Client:
@@ -122,101 +120,15 @@ func SpanOTELGetters(name attr.Name) (attributes.Getter[*Span, attribute.KeyValu
122120
return getter, getter != nil
123121
}
124122

125-
// SpanPromGetters returns the attributes.Getter function that returns the
123+
// spanPromGetters returns the attributes.Getter function that returns the
126124
// Prometheus string value of a given attribute name.
127125
//
128126
//nolint:cyclop
129-
func SpanPromGetters(attrName attr.Name) (attributes.Getter[*Span, string], bool) {
130-
var getter attributes.Getter[*Span, string]
131-
switch attrName {
132-
case attr.HTTPRequestMethod:
133-
getter = func(s *Span) string { return s.Method }
134-
case attr.HTTPResponseStatusCode:
135-
getter = func(s *Span) string { return strconv.Itoa(s.Status) }
136-
case attr.HTTPRoute:
137-
getter = func(s *Span) string { return s.Route }
138-
case attr.HTTPUrlPath:
139-
getter = func(s *Span) string { return s.Path }
140-
case attr.Client, attr.ClientAddr:
141-
getter = PeerAsClient
142-
case attr.Server, attr.ServerAddr:
143-
getter = func(s *Span) string {
144-
if s.Type == EventTypeHTTPClient {
145-
return HTTPClientHost(s)
146-
}
147-
return HostAsServer(s)
148-
}
149-
case attr.ServerPort:
150-
getter = func(s *Span) string { return strconv.Itoa(s.HostPort) }
151-
case attr.RPCMethod:
152-
getter = func(s *Span) string { return s.Path }
153-
case attr.RPCSystem:
154-
getter = func(_ *Span) string { return "grpc" }
155-
case attr.RPCGRPCStatusCode:
156-
getter = func(s *Span) string { return strconv.Itoa(s.Status) }
157-
case attr.DBOperation:
158-
getter = func(span *Span) string { return span.Method }
159-
case attr.ErrorType:
160-
getter = func(span *Span) string {
161-
if SpanStatusCode(span) == StatusCodeError {
162-
return "error"
163-
}
164-
return ""
165-
}
166-
case attr.DBSystemName:
167-
getter = func(span *Span) string {
168-
switch span.Type {
169-
case EventTypeSQLClient:
170-
return span.DBSystemName().Value.AsString()
171-
case EventTypeRedisClient, EventTypeRedisServer:
172-
return semconv.DBSystemRedis.Value.AsString()
173-
case EventTypeMongoClient:
174-
return semconv.DBSystemMongoDB.Value.AsString()
175-
}
176-
return "unknown"
177-
}
178-
case attr.DBCollectionName:
179-
getter = func(span *Span) string {
180-
if span.Type == EventTypeSQLClient {
181-
return span.DBSystemName().Value.AsString()
182-
}
183-
if span.Type == EventTypeMongoClient {
184-
return span.Path
185-
}
186-
return ""
187-
}
188-
case attr.MessagingSystem:
189-
getter = func(span *Span) string {
190-
if span.Type == EventTypeKafkaClient || span.Type == EventTypeKafkaServer {
191-
return "kafka"
192-
}
193-
return "unknown"
194-
}
195-
case attr.MessagingDestination:
196-
getter = func(span *Span) string {
197-
if span.Type == EventTypeKafkaClient || span.Type == EventTypeKafkaServer {
198-
return span.Path
199-
}
200-
return ""
201-
}
202-
case attr.ServiceInstanceID:
203-
getter = func(s *Span) string { return s.Service.UID.Instance }
204-
// resource metadata values below. Unlike OTEL, they are included here because they
205-
// belong to the metric, instead of the Resource
206-
case attr.Instance:
207-
getter = func(s *Span) string { return s.Service.UID.Instance }
208-
case attr.Job:
209-
getter = func(s *Span) string { return s.Service.Job() }
210-
case attr.ServiceName:
211-
getter = func(s *Span) string { return s.Service.UID.Name }
212-
case attr.ServiceNamespace:
213-
getter = func(s *Span) string { return s.Service.UID.Namespace }
214-
case attr.CudaKernelName:
215-
getter = func(s *Span) string { return s.Method }
216-
case attr.CudaMemcpyKind:
217-
getter = func(s *Span) string { return CudaMemcpyName(s.SubType) }
218-
default:
219-
getter = func(s *Span) string { return s.Service.Metadata[attrName] }
127+
func spanPromGetters(attrName attr.Name) (attributes.Getter[*Span, string], bool) {
128+
if otelGetter, ok := spanOTELGetters(attrName); ok {
129+
return func(span *Span) string { return otelGetter(span).Value.Emit() }, true
220130
}
221-
return getter, getter != nil
131+
// unlike the OTEL getters, when the attribute is not found, we need to look for it
132+
// in the metadata section
133+
return func(s *Span) string { return s.Service.Metadata[attrName] }, true
222134
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package request
5+
6+
import (
7+
"go.opentelemetry.io/otel/attribute"
8+
9+
"go.opentelemetry.io/obi/pkg/export/attributes"
10+
)
11+
12+
// SpanOTELGetters returns the proper attributes.NamedGetters implementation for the given
13+
// user-provided configuration.
14+
func SpanOTELGetters(renameUnresolved string) attributes.NamedGetters[*Span, attribute.KeyValue] {
15+
if renameUnresolved == "" {
16+
return spanOTELGetters
17+
}
18+
return otelUnresolvedHostGetters(renameUnresolved)
19+
}
20+
21+
// SpanPromGetters returns the proper attributes.NamedGetters implementation for the given
22+
// user-provided configuration.
23+
func SpanPromGetters(renameUnresolved string) attributes.NamedGetters[*Span, string] {
24+
if renameUnresolved == "" {
25+
return spanPromGetters
26+
}
27+
return promUnresolvedHostGetters(renameUnresolved)
28+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package request
5+
6+
import (
7+
"net"
8+
9+
"go.opentelemetry.io/otel/attribute"
10+
11+
"go.opentelemetry.io/obi/pkg/export/attributes"
12+
attr "go.opentelemetry.io/obi/pkg/export/attributes/names"
13+
)
14+
15+
// otelUnresolvedHostGetters wraps spanOTELGetters but replacing client and server address
16+
// unresolved metrics by a user-provided tag (usually "unresolved")
17+
func otelUnresolvedHostGetters(unresolvedTag string) func(name attr.Name) (attributes.Getter[*Span, attribute.KeyValue], bool) {
18+
return func(name attr.Name) (attributes.Getter[*Span, attribute.KeyValue], bool) {
19+
getter, ok := spanOTELGetters(name)
20+
if name == attr.Client || name == attr.Server {
21+
return func(s *Span) attribute.KeyValue {
22+
kv := getter(s)
23+
if net.ParseIP(kv.Value.AsString()) != nil {
24+
kv.Value = attribute.StringValue(unresolvedTag)
25+
}
26+
return kv
27+
}, true
28+
}
29+
return getter, ok
30+
}
31+
}
32+
33+
// promUnresolvedHostGetters wraps spanPromGetters but replacing client and server address
34+
// unresolved metrics by a user-provided tag (usually "unresolved")
35+
func promUnresolvedHostGetters(unresolvedTag string) func(name attr.Name) (attributes.Getter[*Span, string], bool) {
36+
return func(name attr.Name) (attributes.Getter[*Span, string], bool) {
37+
getter, ok := spanPromGetters(name)
38+
if name == attr.Client || name == attr.Server {
39+
return func(span *Span) string {
40+
val := getter(span)
41+
if net.ParseIP(val) != nil {
42+
return unresolvedTag
43+
}
44+
return val
45+
}, true
46+
}
47+
return getter, ok
48+
}
49+
}

0 commit comments

Comments
 (0)