Skip to content

Commit 5f809d4

Browse files
Support service.{address, port} with fallback to net.peer.* (#110)
Co-authored-by: Gergely Kalapos <[email protected]>
1 parent f3e6bc7 commit 5f809d4

File tree

2 files changed

+92
-9
lines changed

2 files changed

+92
-9
lines changed

enrichments/trace/internal/elastic/span.go

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type spanEnrichmentContext struct {
5656
urlFull *url.URL
5757

5858
peerService string
59+
serverAddress string
5960
urlScheme string
6061
urlDomain string
6162
urlPath string
@@ -68,6 +69,7 @@ type spanEnrichmentContext struct {
6869
messagingSystem string
6970
messagingDestinationName string
7071

72+
serverPort int64
7173
urlPort int64
7274
httpStatusCode int64
7375

@@ -91,6 +93,24 @@ func (s *spanEnrichmentContext) Enrich(span ptrace.Span, cfg config.Config) {
9193
switch k {
9294
case semconv.AttributePeerService:
9395
s.peerService = v.Str()
96+
case semconv.AttributeServerAddress:
97+
s.serverAddress = v.Str()
98+
case semconv.AttributeServerPort:
99+
s.serverPort = v.Int()
100+
case semconv.AttributeNetPeerName:
101+
if s.serverAddress == "" {
102+
// net.peer.name is deprecated, so has lower priority
103+
// only set when not already set with server.address
104+
// and allowed to be overridden by server.address.
105+
s.serverAddress = v.Str()
106+
}
107+
case semconv.AttributeNetPeerPort:
108+
if s.serverPort == 0 {
109+
// net.peer.port is deprecated, so has lower priority
110+
// only set when not already set with server.port and
111+
// allowed to be overridden by server.port.
112+
s.serverPort = v.Int()
113+
}
94114
case semconv.AttributeMessagingDestinationName:
95115
s.isMessaging = true
96116
s.messagingDestinationName = v.Str()
@@ -385,7 +405,10 @@ func (s *spanEnrichmentContext) setServiceTarget(span ptrace.Span) {
385405
}
386406
case s.isHTTP:
387407
targetType = "http"
388-
if resource := getHostPort(s.urlFull, s.urlDomain, s.urlPort); resource != "" {
408+
if resource := getHostPort(
409+
s.urlFull, s.urlDomain, s.urlPort,
410+
s.serverAddress, s.serverPort, // fallback
411+
); resource != "" {
389412
targetName = resource
390413
}
391414
}
@@ -419,7 +442,10 @@ func (s *spanEnrichmentContext) setDestinationService(span ptrace.Span) {
419442
}
420443
case s.isRPC, s.isHTTP:
421444
if destnResource == "" {
422-
if res := getHostPort(s.urlFull, s.urlDomain, s.urlPort); res != "" {
445+
if res := getHostPort(
446+
s.urlFull, s.urlDomain, s.urlPort,
447+
s.serverAddress, s.serverPort, // fallback
448+
); res != "" {
423449
destnResource = res
424450
}
425451
}
@@ -585,18 +611,23 @@ func getValueForKeyInString(str string, key string, separator rune, assignChar r
585611
return ""
586612
}
587613

588-
// getHostPort derives the host:port value from url.* attributes. Unlike
589-
// apm-data, the current code does NOT fallback to net.* or http.*
590-
// attributes as most of these are now deprecated.
591-
func getHostPort(urlFull *url.URL, urlDomain string, urlPort int64) string {
592-
if urlFull != nil {
614+
func getHostPort(
615+
urlFull *url.URL, urlDomain string, urlPort int64,
616+
fallbackServerAddress string, fallbackServerPort int64,
617+
) string {
618+
switch {
619+
case urlFull != nil:
593620
return urlFull.Host
594-
}
595-
if urlDomain != "" {
621+
case urlDomain != "":
596622
if urlPort == 0 {
597623
return urlDomain
598624
}
599625
return net.JoinHostPort(urlDomain, strconv.FormatInt(urlPort, 10))
626+
case fallbackServerAddress != "":
627+
if fallbackServerPort == 0 {
628+
return fallbackServerAddress
629+
}
630+
return net.JoinHostPort(fallbackServerAddress, strconv.FormatInt(fallbackServerPort, 10))
600631
}
601632
return ""
602633
}

enrichments/trace/internal/elastic/span_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,58 @@ func TestElasticSpanEnrich(t *testing.T) {
632632
AttributeSpanDestinationServiceResource: "testsvc",
633633
},
634634
},
635+
{
636+
name: "rpc_span_service.{address, port}",
637+
input: func() ptrace.Span {
638+
span := getElasticSpan()
639+
span.SetName("testspan")
640+
// No peer.service is set
641+
span.Attributes().PutStr(semconv.AttributeRPCService, "service.Test")
642+
span.Attributes().PutStr(semconv.AttributeServerAddress, "10.2.20.18")
643+
span.Attributes().PutInt(semconv.AttributeServerPort, 8081)
644+
return span
645+
}(),
646+
config: config.Enabled().Span,
647+
enrichedAttrs: map[string]any{
648+
AttributeTimestampUs: startTs.AsTime().UnixMicro(),
649+
AttributeSpanName: "testspan",
650+
AttributeProcessorEvent: "span",
651+
AttributeSpanRepresentativeCount: float64(1),
652+
AttributeSpanType: "external",
653+
AttributeSpanDurationUs: expectedDuration.Microseconds(),
654+
AttributeEventOutcome: "success",
655+
AttributeSuccessCount: int64(1),
656+
AttributeServiceTargetType: "external",
657+
AttributeServiceTargetName: "service.Test",
658+
AttributeSpanDestinationServiceResource: "10.2.20.18:8081",
659+
},
660+
},
661+
{
662+
name: "rpc_span_net.peer.{address, port}_fallback",
663+
input: func() ptrace.Span {
664+
span := getElasticSpan()
665+
span.SetName("testspan")
666+
// No peer.service is set
667+
span.Attributes().PutStr(semconv.AttributeRPCService, "service.Test")
668+
span.Attributes().PutStr(semconv.AttributeNetPeerName, "10.2.20.18")
669+
span.Attributes().PutInt(semconv.AttributeNetPeerPort, 8081)
670+
return span
671+
}(),
672+
config: config.Enabled().Span,
673+
enrichedAttrs: map[string]any{
674+
AttributeTimestampUs: startTs.AsTime().UnixMicro(),
675+
AttributeSpanName: "testspan",
676+
AttributeProcessorEvent: "span",
677+
AttributeSpanRepresentativeCount: float64(1),
678+
AttributeSpanType: "external",
679+
AttributeSpanDurationUs: expectedDuration.Microseconds(),
680+
AttributeEventOutcome: "success",
681+
AttributeSuccessCount: int64(1),
682+
AttributeServiceTargetType: "external",
683+
AttributeServiceTargetName: "service.Test",
684+
AttributeSpanDestinationServiceResource: "10.2.20.18:8081",
685+
},
686+
},
635687
{
636688
name: "messaging_basic",
637689
input: func() ptrace.Span {

0 commit comments

Comments
 (0)