Skip to content

Commit 881c4ef

Browse files
committed
Add enrichment for span.destination.service.resource
1 parent 8eda486 commit 881c4ef

File tree

4 files changed

+117
-62
lines changed

4 files changed

+117
-62
lines changed

enrichments/trace/config/config.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ type ElasticTransactionConfig struct {
4343
// ElasticSpanConfig configures the enrichment attributes for the spans
4444
// which are NOT identified as elastic transaction.
4545
type ElasticSpanConfig struct {
46-
Name AttributeConfig `mapstructure:"name"`
47-
EventOutcome AttributeConfig `mapstructure:"event_outcome"`
48-
ServiceTarget AttributeConfig `mapstructure:"service_target"`
46+
Name AttributeConfig `mapstructure:"name"`
47+
EventOutcome AttributeConfig `mapstructure:"event_outcome"`
48+
ServiceTarget AttributeConfig `mapstructure:"service_target"`
49+
DestinationService AttributeConfig `mapstructure:"destination_service"`
4950
}
5051

5152
// AttributeConfig is the configuration options for each attribute.
@@ -68,9 +69,10 @@ func Enabled() Config {
6869
EventOutcome: AttributeConfig{Enabled: true},
6970
},
7071
Span: ElasticSpanConfig{
71-
Name: AttributeConfig{Enabled: true},
72-
EventOutcome: AttributeConfig{Enabled: true},
73-
ServiceTarget: AttributeConfig{Enabled: true},
72+
Name: AttributeConfig{Enabled: true},
73+
EventOutcome: AttributeConfig{Enabled: true},
74+
ServiceTarget: AttributeConfig{Enabled: true},
75+
DestinationService: AttributeConfig{Enabled: true},
7476
},
7577
}
7678
}

enrichments/trace/internal/elastic/attributes.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ const (
2323
AttributeAgentVersion = "agent.version"
2424

2525
// span attributes
26-
AttributeTransactionRoot = "transaction.root"
27-
AttributeTransactionName = "transaction.name"
28-
AttributeTransactionType = "transaction.type"
29-
AttributeTransactionResult = "transaction.result"
30-
AttributeSpanName = "span.name"
31-
AttributeEventOutcome = "event.outcome"
32-
AttributeServiceTargetType = "service.target.type"
33-
AttributeServiceTargetName = "service.target.name"
26+
AttributeTransactionRoot = "transaction.root"
27+
AttributeTransactionName = "transaction.name"
28+
AttributeTransactionType = "transaction.type"
29+
AttributeTransactionResult = "transaction.result"
30+
AttributeSpanName = "span.name"
31+
AttributeEventOutcome = "event.outcome"
32+
AttributeServiceTargetType = "service.target.type"
33+
AttributeServiceTargetName = "service.target.name"
34+
AttributeSpanDestinationResource = "span.destination.service.resource"
3435
)

enrichments/trace/internal/elastic/span.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ func (s *spanEnrichmentContext) enrichSpan(
191191
if cfg.ServiceTarget.Enabled {
192192
s.setServiceTarget(span)
193193
}
194+
if cfg.DestinationService.Enabled {
195+
s.setDestinationService(span)
196+
}
194197
}
195198

196199
// normalizeAttributes sets any dependent attributes that
@@ -300,6 +303,40 @@ func (s *spanEnrichmentContext) setServiceTarget(span ptrace.Span) {
300303
}
301304
}
302305

306+
func (s *spanEnrichmentContext) setDestinationService(span ptrace.Span) {
307+
var destnResource string
308+
if s.peerService != "" {
309+
destnResource = s.peerService
310+
}
311+
312+
switch {
313+
case s.isDB:
314+
if destnResource == "" && s.dbType != "" {
315+
destnResource = s.dbType
316+
}
317+
case s.isMessaging:
318+
if destnResource == "" && s.messagingSystem != "" {
319+
destnResource = s.messagingSystem
320+
}
321+
// For parity with apm-data, destn resource does not handle
322+
// temporary destination flag. However, it is handled by
323+
// service.target fields and we might want to do the same here.
324+
if destnResource != "" && s.messagingDestinationName != "" {
325+
destnResource += "/" + s.messagingDestinationName
326+
}
327+
case s.isRPC, s.isHTTP:
328+
if destnResource == "" {
329+
if res := getHostPort(s.urlFull, s.urlDomain, s.urlPort); res != "" {
330+
destnResource = res
331+
}
332+
}
333+
}
334+
335+
if destnResource != "" {
336+
span.Attributes().PutStr(AttributeSpanDestinationResource, destnResource)
337+
}
338+
}
339+
303340
func isTraceRoot(span ptrace.Span) bool {
304341
return span.ParentSpanID().IsEmpty()
305342
}
@@ -319,6 +356,9 @@ func isElasticTransaction(span ptrace.Span) bool {
319356
return false
320357
}
321358

359+
// getHostPort derives the host:port value from url.* attributes. Unlike
360+
// apm-data, the current code does NOT fallback to net.* or http.*
361+
// attritubtes as most of these are now deprecated.
322362
func getHostPort(urlFull *url.URL, urlDomain string, urlPort int64) string {
323363
if urlFull != nil {
324364
return urlFull.Host

enrichments/trace/internal/elastic/span_test.go

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,11 @@ func TestElasticSpanEnrich(t *testing.T) {
265265
}(),
266266
config: config.Enabled().Span,
267267
enrichedAttrs: map[string]any{
268-
AttributeSpanName: "testspan",
269-
AttributeEventOutcome: "success",
270-
AttributeServiceTargetName: "testsvc",
271-
AttributeServiceTargetType: "",
268+
AttributeSpanName: "testspan",
269+
AttributeEventOutcome: "success",
270+
AttributeServiceTargetName: "testsvc",
271+
AttributeServiceTargetType: "",
272+
AttributeSpanDestinationResource: "testsvc",
272273
},
273274
},
274275
{
@@ -285,10 +286,11 @@ func TestElasticSpanEnrich(t *testing.T) {
285286
}(),
286287
config: config.Enabled().Span,
287288
enrichedAttrs: map[string]any{
288-
AttributeSpanName: "testspan",
289-
AttributeEventOutcome: "success",
290-
AttributeServiceTargetType: "http",
291-
AttributeServiceTargetName: "testsvc",
289+
AttributeSpanName: "testspan",
290+
AttributeEventOutcome: "success",
291+
AttributeServiceTargetType: "http",
292+
AttributeServiceTargetName: "testsvc",
293+
AttributeSpanDestinationResource: "testsvc",
292294
},
293295
},
294296
{
@@ -311,10 +313,11 @@ func TestElasticSpanEnrich(t *testing.T) {
311313
}(),
312314
config: config.Enabled().Span,
313315
enrichedAttrs: map[string]any{
314-
AttributeSpanName: "testspan",
315-
AttributeEventOutcome: "success",
316-
AttributeServiceTargetType: "http",
317-
AttributeServiceTargetName: "www.foo.bar:443",
316+
AttributeSpanName: "testspan",
317+
AttributeEventOutcome: "success",
318+
AttributeServiceTargetType: "http",
319+
AttributeServiceTargetName: "www.foo.bar:443",
320+
AttributeSpanDestinationResource: "testsvc",
318321
},
319322
},
320323
{
@@ -335,10 +338,11 @@ func TestElasticSpanEnrich(t *testing.T) {
335338
}(),
336339
config: config.Enabled().Span,
337340
enrichedAttrs: map[string]any{
338-
AttributeSpanName: "testspan",
339-
AttributeEventOutcome: "success",
340-
AttributeServiceTargetType: "http",
341-
AttributeServiceTargetName: "www.foo.bar:443",
341+
AttributeSpanName: "testspan",
342+
AttributeEventOutcome: "success",
343+
AttributeServiceTargetType: "http",
344+
AttributeServiceTargetName: "www.foo.bar:443",
345+
AttributeSpanDestinationResource: "testsvc",
342346
},
343347
},
344348
{
@@ -355,10 +359,11 @@ func TestElasticSpanEnrich(t *testing.T) {
355359
}(),
356360
config: config.Enabled().Span,
357361
enrichedAttrs: map[string]any{
358-
AttributeSpanName: "testspan",
359-
AttributeEventOutcome: "success",
360-
AttributeServiceTargetType: "grpc",
361-
AttributeServiceTargetName: "testsvc",
362+
AttributeSpanName: "testspan",
363+
AttributeEventOutcome: "success",
364+
AttributeServiceTargetType: "grpc",
365+
AttributeServiceTargetName: "testsvc",
366+
AttributeSpanDestinationResource: "testsvc",
362367
},
363368
},
364369
{
@@ -372,10 +377,11 @@ func TestElasticSpanEnrich(t *testing.T) {
372377
}(),
373378
config: config.Enabled().Span,
374379
enrichedAttrs: map[string]any{
375-
AttributeSpanName: "testspan",
376-
AttributeEventOutcome: "success",
377-
AttributeServiceTargetType: "xmlrpc",
378-
AttributeServiceTargetName: "testsvc",
380+
AttributeSpanName: "testspan",
381+
AttributeEventOutcome: "success",
382+
AttributeServiceTargetType: "xmlrpc",
383+
AttributeServiceTargetName: "testsvc",
384+
AttributeSpanDestinationResource: "testsvc",
379385
},
380386
},
381387
{
@@ -391,10 +397,11 @@ func TestElasticSpanEnrich(t *testing.T) {
391397
}(),
392398
config: config.Enabled().Span,
393399
enrichedAttrs: map[string]any{
394-
AttributeSpanName: "testspan",
395-
AttributeEventOutcome: "success",
396-
AttributeServiceTargetType: "external",
397-
AttributeServiceTargetName: "service.Test",
400+
AttributeSpanName: "testspan",
401+
AttributeEventOutcome: "success",
402+
AttributeServiceTargetType: "external",
403+
AttributeServiceTargetName: "service.Test",
404+
AttributeSpanDestinationResource: "testsvc",
398405
},
399406
},
400407
{
@@ -408,10 +415,11 @@ func TestElasticSpanEnrich(t *testing.T) {
408415
}(),
409416
config: config.Enabled().Span,
410417
enrichedAttrs: map[string]any{
411-
AttributeSpanName: "testspan",
412-
AttributeEventOutcome: "success",
413-
AttributeServiceTargetType: "kafka",
414-
AttributeServiceTargetName: "testsvc",
418+
AttributeSpanName: "testspan",
419+
AttributeEventOutcome: "success",
420+
AttributeServiceTargetType: "kafka",
421+
AttributeServiceTargetName: "testsvc",
422+
AttributeSpanDestinationResource: "testsvc",
415423
},
416424
},
417425
{
@@ -425,10 +433,11 @@ func TestElasticSpanEnrich(t *testing.T) {
425433
}(),
426434
config: config.Enabled().Span,
427435
enrichedAttrs: map[string]any{
428-
AttributeSpanName: "testspan",
429-
AttributeEventOutcome: "success",
430-
AttributeServiceTargetType: "messaging",
431-
AttributeServiceTargetName: "t1",
436+
AttributeSpanName: "testspan",
437+
AttributeEventOutcome: "success",
438+
AttributeServiceTargetType: "messaging",
439+
AttributeServiceTargetName: "t1",
440+
AttributeSpanDestinationResource: "testsvc/t1",
432441
},
433442
},
434443
{
@@ -443,10 +452,11 @@ func TestElasticSpanEnrich(t *testing.T) {
443452
}(),
444453
config: config.Enabled().Span,
445454
enrichedAttrs: map[string]any{
446-
AttributeSpanName: "testspan",
447-
AttributeEventOutcome: "success",
448-
AttributeServiceTargetType: "messaging",
449-
AttributeServiceTargetName: "testsvc",
455+
AttributeSpanName: "testspan",
456+
AttributeEventOutcome: "success",
457+
AttributeServiceTargetType: "messaging",
458+
AttributeServiceTargetName: "testsvc",
459+
AttributeSpanDestinationResource: "testsvc/t1",
450460
},
451461
},
452462
{
@@ -467,10 +477,11 @@ func TestElasticSpanEnrich(t *testing.T) {
467477
}(),
468478
config: config.Enabled().Span,
469479
enrichedAttrs: map[string]any{
470-
AttributeSpanName: "testspan",
471-
AttributeEventOutcome: "success",
472-
AttributeServiceTargetType: "elasticsearch",
473-
AttributeServiceTargetName: "testsvc",
480+
AttributeSpanName: "testspan",
481+
AttributeEventOutcome: "success",
482+
AttributeServiceTargetType: "elasticsearch",
483+
AttributeServiceTargetName: "testsvc",
484+
AttributeSpanDestinationResource: "testsvc",
474485
},
475486
},
476487
{
@@ -496,10 +507,11 @@ func TestElasticSpanEnrich(t *testing.T) {
496507
}(),
497508
config: config.Enabled().Span,
498509
enrichedAttrs: map[string]any{
499-
AttributeSpanName: "testspan",
500-
AttributeEventOutcome: "success",
501-
AttributeServiceTargetType: "cassandra",
502-
AttributeServiceTargetName: "testsvc",
510+
AttributeSpanName: "testspan",
511+
AttributeEventOutcome: "success",
512+
AttributeServiceTargetType: "cassandra",
513+
AttributeServiceTargetName: "testsvc",
514+
AttributeSpanDestinationResource: "testsvc",
503515
},
504516
},
505517
} {

0 commit comments

Comments
 (0)