From aaff9419055336e4e7948c52e2ceefa132e64f9d Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 23 Apr 2025 17:13:27 +0200 Subject: [PATCH 01/10] Add test for mobile transaction enrichment --- .../trace/internal/elastic/span_test.go | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/enrichments/trace/internal/elastic/span_test.go b/enrichments/trace/internal/elastic/span_test.go index 52460bb..30cc6d2 100644 --- a/enrichments/trace/internal/elastic/span_test.go +++ b/enrichments/trace/internal/elastic/span_test.go @@ -446,6 +446,140 @@ func TestElasticTransactionEnrich(t *testing.T) { } } +// Tests the enrichment logic for elastic's transaction definition for mobile agents. +func TestElasticTransactionEnrichForMobile(t *testing.T) { + now := time.Unix(3600, 0) + expectedDuration := time.Minute + endTs := pcommon.NewTimestampFromTime(now) + startTs := pcommon.NewTimestampFromTime(now.Add(-1 * expectedDuration)) + getElasticMobileTxn := func() ptrace.Span { + span := ptrace.NewSpan() + span.SetSpanID([8]byte{1}) + span.SetStartTimestamp(startTs) + span.SetEndTimestamp(endTs) + span.Attributes().PutStr("type", "mobile") + return span + } + for _, tc := range []struct { + name string + input ptrace.Span + config config.ElasticTransactionConfig + enrichedAttrs map[string]any + expectedSpanLinks *ptrace.SpanLinkSlice + }{ + { + // test case gives a summary of what is emitted by default + name: "empty", + input: func() ptrace.Span { + span := ptrace.NewSpan() + span.Attributes().PutStr("type", "mobile") + return span + }(), + config: config.Enabled().Transaction, + enrichedAttrs: map[string]any{ + elasticattr.TimestampUs: int64(0), + elasticattr.TransactionSampled: true, + elasticattr.TransactionRoot: true, + elasticattr.TransactionID: "", + elasticattr.TransactionName: "", + elasticattr.ProcessorEvent: "transaction", + elasticattr.TransactionRepresentativeCount: float64(1), + elasticattr.TransactionDurationUs: int64(0), + elasticattr.EventOutcome: "success", + elasticattr.SuccessCount: int64(1), + elasticattr.TransactionResult: "Success", + elasticattr.TransactionType: "mobile", + }, + }, + { + name: "all_disabled", + input: getElasticMobileTxn(), + enrichedAttrs: map[string]any{}, + }, + { + name: "http_status_ok", + input: func() ptrace.Span { + span := getElasticMobileTxn() + span.SetName("testtxn") + span.Attributes().PutInt(semconv25.AttributeHTTPStatusCode, http.StatusOK) + return span + }(), + config: config.Enabled().Transaction, + enrichedAttrs: map[string]any{ + elasticattr.TimestampUs: startTs.AsTime().UnixMicro(), + elasticattr.TransactionSampled: true, + elasticattr.TransactionRoot: true, + elasticattr.TransactionID: "0100000000000000", + elasticattr.TransactionName: "testtxn", + elasticattr.ProcessorEvent: "transaction", + elasticattr.TransactionRepresentativeCount: float64(1), + elasticattr.TransactionDurationUs: expectedDuration.Microseconds(), + elasticattr.EventOutcome: "success", + elasticattr.SuccessCount: int64(1), + elasticattr.TransactionResult: "HTTP 2xx", + elasticattr.TransactionType: "mobile", + }, + }, + { + name: "outgoing_http_root_span", + input: func() ptrace.Span { + span := getElasticMobileTxn() + span.SetName("rootClientSpan") + span.SetKind(ptrace.SpanKindClient) + span.Attributes().PutStr(semconv27.AttributeHTTPRequestMethod, "GET") + span.Attributes().PutStr(semconv27.AttributeURLFull, "http://localhost:8080") + span.Attributes().PutInt(semconv27.AttributeHTTPResponseStatusCode, 200) + span.Attributes().PutStr(semconv27.AttributeNetworkProtocolVersion, "1.1") + return span + }(), + config: config.Enabled().Transaction, + enrichedAttrs: map[string]any{ + elasticattr.TimestampUs: int64(0), + elasticattr.TransactionName: "rootClientSpan", + elasticattr.ProcessorEvent: "transaction", + elasticattr.SpanType: "external", + elasticattr.SpanSubtype: "http", + elasticattr.SpanDestinationServiceResource: "localhost:8080", + elasticattr.SpanName: "rootClientSpan", + elasticattr.EventOutcome: "success", + elasticattr.SuccessCount: int64(1), + elasticattr.ServiceTargetName: "localhost:8080", + elasticattr.ServiceTargetType: "http", + elasticattr.TransactionID: "0100000000000000", + elasticattr.TransactionDurationUs: int64(0), + elasticattr.TransactionRepresentativeCount: float64(1), + elasticattr.TransactionResult: "HTTP 2xx", + elasticattr.TransactionType: "mobile", + elasticattr.TransactionSampled: true, + elasticattr.TransactionRoot: true, + elasticattr.SpanDurationUs: int64(0), + elasticattr.SpanRepresentativeCount: float64(1), + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + expectedSpan := ptrace.NewSpan() + tc.input.CopyTo(expectedSpan) + + // Merge with the expected attributes and override the span links. + for k, v := range tc.enrichedAttrs { + expectedSpan.Attributes().PutEmpty(k).FromRaw(v) + } + // Override span links + if tc.expectedSpanLinks != nil { + tc.expectedSpanLinks.CopyTo(expectedSpan.Links()) + } else { + expectedSpan.Links().RemoveIf(func(_ ptrace.SpanLink) bool { return true }) + } + + EnrichSpan(tc.input, config.Config{ + Transaction: tc.config, + }, uaparser.NewFromSaved()) + assert.NoError(t, ptracetest.CompareSpan(expectedSpan, tc.input)) + }) + } +} + // Tests root spans that represent a dependency and are mapped to a transaction. func TestRootSpanAsDependencyEnrich(t *testing.T) { for _, tc := range []struct { From 99974126a2a8ebb99b5905539787008cde9e6505 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 23 Apr 2025 17:26:36 +0200 Subject: [PATCH 02/10] Add mobile transaction type for mobile transactions --- enrichments/trace/internal/elastic/span.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index 30de8af..8d1a83d 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -98,6 +98,7 @@ type spanEnrichmentContext struct { isDB bool messagingDestinationTemp bool isGenAi bool + isMobile bool } func (s *spanEnrichmentContext) Enrich( @@ -200,6 +201,10 @@ func (s *spanEnrichmentContext) Enrich( s.userAgentName = v.Str() case semconv27.AttributeUserAgentVersion: s.userAgentVersion = v.Str() + case "type": + if v.Str() == "mobile" { + s.isMobile = true + } } return true }) @@ -355,6 +360,8 @@ func (s *spanEnrichmentContext) getTxnType() string { txnType = "messaging" case s.isRPC, s.isHTTP: txnType = "request" + case s.isMobile: + txnType = "mobile" } return txnType } From 4ad98bb2ca3914b728d22c0f6e213d7293d2d78f Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 23 Apr 2025 17:42:26 +0200 Subject: [PATCH 03/10] Updating tests --- enrichments/trace/internal/elastic/span.go | 4 ++-- enrichments/trace/internal/elastic/span_test.go | 16 +++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index 8d1a83d..10660fa 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -356,12 +356,12 @@ func (s *spanEnrichmentContext) getSampled() bool { func (s *spanEnrichmentContext) getTxnType() string { txnType := "unknown" switch { + case s.isMobile: + txnType = "mobile" case s.isMessaging: txnType = "messaging" case s.isRPC, s.isHTTP: txnType = "request" - case s.isMobile: - txnType = "mobile" } return txnType } diff --git a/enrichments/trace/internal/elastic/span_test.go b/enrichments/trace/internal/elastic/span_test.go index 30cc6d2..f65d87b 100644 --- a/enrichments/trace/internal/elastic/span_test.go +++ b/enrichments/trace/internal/elastic/span_test.go @@ -463,7 +463,7 @@ func TestElasticTransactionEnrichForMobile(t *testing.T) { for _, tc := range []struct { name string input ptrace.Span - config config.ElasticTransactionConfig + config config.Config enrichedAttrs map[string]any expectedSpanLinks *ptrace.SpanLinkSlice }{ @@ -475,7 +475,7 @@ func TestElasticTransactionEnrichForMobile(t *testing.T) { span.Attributes().PutStr("type", "mobile") return span }(), - config: config.Enabled().Transaction, + config: config.Enabled(), enrichedAttrs: map[string]any{ elasticattr.TimestampUs: int64(0), elasticattr.TransactionSampled: true, @@ -504,7 +504,7 @@ func TestElasticTransactionEnrichForMobile(t *testing.T) { span.Attributes().PutInt(semconv25.AttributeHTTPStatusCode, http.StatusOK) return span }(), - config: config.Enabled().Transaction, + config: config.Enabled(), enrichedAttrs: map[string]any{ elasticattr.TimestampUs: startTs.AsTime().UnixMicro(), elasticattr.TransactionSampled: true, @@ -532,9 +532,9 @@ func TestElasticTransactionEnrichForMobile(t *testing.T) { span.Attributes().PutStr(semconv27.AttributeNetworkProtocolVersion, "1.1") return span }(), - config: config.Enabled().Transaction, + config: config.Enabled(), enrichedAttrs: map[string]any{ - elasticattr.TimestampUs: int64(0), + elasticattr.TimestampUs: startTs.AsTime().UnixMicro(), elasticattr.TransactionName: "rootClientSpan", elasticattr.ProcessorEvent: "transaction", elasticattr.SpanType: "external", @@ -546,7 +546,7 @@ func TestElasticTransactionEnrichForMobile(t *testing.T) { elasticattr.ServiceTargetName: "localhost:8080", elasticattr.ServiceTargetType: "http", elasticattr.TransactionID: "0100000000000000", - elasticattr.TransactionDurationUs: int64(0), + elasticattr.TransactionDurationUs: expectedDuration.Microseconds(), elasticattr.TransactionRepresentativeCount: float64(1), elasticattr.TransactionResult: "HTTP 2xx", elasticattr.TransactionType: "mobile", @@ -572,9 +572,7 @@ func TestElasticTransactionEnrichForMobile(t *testing.T) { expectedSpan.Links().RemoveIf(func(_ ptrace.SpanLink) bool { return true }) } - EnrichSpan(tc.input, config.Config{ - Transaction: tc.config, - }, uaparser.NewFromSaved()) + EnrichSpan(tc.input, tc.config, uaparser.NewFromSaved()) assert.NoError(t, ptracetest.CompareSpan(expectedSpan, tc.input)) }) } From efbb0744d80e8edf0eaedc18f2e9b433710b981e Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 23 Apr 2025 18:06:50 +0200 Subject: [PATCH 04/10] Do not set transaction type based on span type for mobile spans --- enrichments/trace/internal/elastic/span.go | 2 +- enrichments/trace/internal/elastic/span_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index 10660fa..339bd4b 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -324,7 +324,7 @@ func (s *spanEnrichmentContext) enrichSpan( s.setUserAgentIfRequired(span) } - if isExitRootSpan && transactionTypeEnabled { + if isExitRootSpan && transactionTypeEnabled && !s.isMobile { if spanType != "" { transactionType := spanType if spanSubtype != "" { diff --git a/enrichments/trace/internal/elastic/span_test.go b/enrichments/trace/internal/elastic/span_test.go index f65d87b..1113399 100644 --- a/enrichments/trace/internal/elastic/span_test.go +++ b/enrichments/trace/internal/elastic/span_test.go @@ -552,7 +552,7 @@ func TestElasticTransactionEnrichForMobile(t *testing.T) { elasticattr.TransactionType: "mobile", elasticattr.TransactionSampled: true, elasticattr.TransactionRoot: true, - elasticattr.SpanDurationUs: int64(0), + elasticattr.SpanDurationUs: expectedDuration.Microseconds(), elasticattr.SpanRepresentativeCount: float64(1), }, }, From 802ccb3b24ab6637f37ed569a20529dcc3263c0d Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 25 Apr 2025 10:35:34 +0200 Subject: [PATCH 05/10] Using provided type as transaction.type --- enrichments/trace/internal/elastic/span.go | 14 +++++++------- enrichments/trace/internal/elastic/span_test.go | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index 339bd4b..79e3e70 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -76,6 +76,7 @@ type spanEnrichmentContext struct { messagingSystem string messagingDestinationName string genAiSystem string + typeValue string // The inferred* attributes are derived from a base attribute userAgentOriginal string @@ -98,7 +99,7 @@ type spanEnrichmentContext struct { isDB bool messagingDestinationTemp bool isGenAi bool - isMobile bool + hasType bool } func (s *spanEnrichmentContext) Enrich( @@ -202,9 +203,8 @@ func (s *spanEnrichmentContext) Enrich( case semconv27.AttributeUserAgentVersion: s.userAgentVersion = v.Str() case "type": - if v.Str() == "mobile" { - s.isMobile = true - } + s.hasType = true + s.typeValue = v.Str() } return true }) @@ -324,7 +324,7 @@ func (s *spanEnrichmentContext) enrichSpan( s.setUserAgentIfRequired(span) } - if isExitRootSpan && transactionTypeEnabled && !s.isMobile { + if isExitRootSpan && transactionTypeEnabled && !s.hasType { if spanType != "" { transactionType := spanType if spanSubtype != "" { @@ -356,8 +356,8 @@ func (s *spanEnrichmentContext) getSampled() bool { func (s *spanEnrichmentContext) getTxnType() string { txnType := "unknown" switch { - case s.isMobile: - txnType = "mobile" + case s.hasType: + txnType = s.typeValue case s.isMessaging: txnType = "messaging" case s.isRPC, s.isHTTP: diff --git a/enrichments/trace/internal/elastic/span_test.go b/enrichments/trace/internal/elastic/span_test.go index 1113399..da57edc 100644 --- a/enrichments/trace/internal/elastic/span_test.go +++ b/enrichments/trace/internal/elastic/span_test.go @@ -446,8 +446,8 @@ func TestElasticTransactionEnrich(t *testing.T) { } } -// Tests the enrichment logic for elastic's transaction definition for mobile agents. -func TestElasticTransactionEnrichForMobile(t *testing.T) { +// Tests the enrichment logic for elastic's transaction definition with type. +func TestElasticTransactionEnrichWithType(t *testing.T) { now := time.Unix(3600, 0) expectedDuration := time.Minute endTs := pcommon.NewTimestampFromTime(now) From f65cbd1a7d50f1604d610e5f5dce1b5a4b693085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 25 Apr 2025 12:18:56 +0200 Subject: [PATCH 06/10] Update enrichments/trace/internal/elastic/span.go Co-authored-by: Vishal Raj --- enrichments/trace/internal/elastic/span.go | 1 - 1 file changed, 1 deletion(-) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index 79e3e70..84a9ff2 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -203,7 +203,6 @@ func (s *spanEnrichmentContext) Enrich( case semconv27.AttributeUserAgentVersion: s.userAgentVersion = v.Str() case "type": - s.hasType = true s.typeValue = v.Str() } return true From f78e4f7997ce04db3ddfb06aa34ad4d1bf4183fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 25 Apr 2025 12:19:03 +0200 Subject: [PATCH 07/10] Update enrichments/trace/internal/elastic/span.go Co-authored-by: Vishal Raj --- enrichments/trace/internal/elastic/span.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index 84a9ff2..b26b987 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -355,7 +355,7 @@ func (s *spanEnrichmentContext) getSampled() bool { func (s *spanEnrichmentContext) getTxnType() string { txnType := "unknown" switch { - case s.hasType: + case s.typeValue != "": txnType = s.typeValue case s.isMessaging: txnType = "messaging" From 065e126d5bedc676525c2e32adb05652d3ffb1ce Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 25 Apr 2025 12:20:52 +0200 Subject: [PATCH 08/10] Cleaning up --- enrichments/trace/internal/elastic/span.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index b26b987..f4d1082 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -99,7 +99,6 @@ type spanEnrichmentContext struct { isDB bool messagingDestinationTemp bool isGenAi bool - hasType bool } func (s *spanEnrichmentContext) Enrich( @@ -323,7 +322,7 @@ func (s *spanEnrichmentContext) enrichSpan( s.setUserAgentIfRequired(span) } - if isExitRootSpan && transactionTypeEnabled && !s.hasType { + if isExitRootSpan && transactionTypeEnabled && s.typeValue == "" { if spanType != "" { transactionType := spanType if spanSubtype != "" { From 60b5dd70024af5910952da707ce1c188c2b5c5c0 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 25 Apr 2025 12:31:11 +0200 Subject: [PATCH 09/10] Updating tests --- .../trace/internal/elastic/span_test.go | 144 +++++++++++------- 1 file changed, 93 insertions(+), 51 deletions(-) diff --git a/enrichments/trace/internal/elastic/span_test.go b/enrichments/trace/internal/elastic/span_test.go index da57edc..ffe9357 100644 --- a/enrichments/trace/internal/elastic/span_test.go +++ b/enrichments/trace/internal/elastic/span_test.go @@ -51,6 +51,11 @@ func TestElasticTransactionEnrich(t *testing.T) { span.SetEndTimestamp(endTs) return span } + getElasticMobileTxn := func() ptrace.Span { + span := getElasticTxn() + span.Attributes().PutStr("type", "mobile") + return span + } for _, tc := range []struct { name string input ptrace.Span @@ -422,60 +427,14 @@ func TestElasticTransactionEnrich(t *testing.T) { semconv27.AttributeUserAgentVersion: "51.0.2704", }, }, - } { - t.Run(tc.name, func(t *testing.T) { - expectedSpan := ptrace.NewSpan() - tc.input.CopyTo(expectedSpan) - - // Merge with the expected attributes and override the span links. - for k, v := range tc.enrichedAttrs { - expectedSpan.Attributes().PutEmpty(k).FromRaw(v) - } - // Override span links - if tc.expectedSpanLinks != nil { - tc.expectedSpanLinks.CopyTo(expectedSpan.Links()) - } else { - expectedSpan.Links().RemoveIf(func(_ ptrace.SpanLink) bool { return true }) - } - - EnrichSpan(tc.input, config.Config{ - Transaction: tc.config, - }, uaparser.NewFromSaved()) - assert.NoError(t, ptracetest.CompareSpan(expectedSpan, tc.input)) - }) - } -} - -// Tests the enrichment logic for elastic's transaction definition with type. -func TestElasticTransactionEnrichWithType(t *testing.T) { - now := time.Unix(3600, 0) - expectedDuration := time.Minute - endTs := pcommon.NewTimestampFromTime(now) - startTs := pcommon.NewTimestampFromTime(now.Add(-1 * expectedDuration)) - getElasticMobileTxn := func() ptrace.Span { - span := ptrace.NewSpan() - span.SetSpanID([8]byte{1}) - span.SetStartTimestamp(startTs) - span.SetEndTimestamp(endTs) - span.Attributes().PutStr("type", "mobile") - return span - } - for _, tc := range []struct { - name string - input ptrace.Span - config config.Config - enrichedAttrs map[string]any - expectedSpanLinks *ptrace.SpanLinkSlice - }{ { - // test case gives a summary of what is emitted by default - name: "empty", + name: "with_type", input: func() ptrace.Span { span := ptrace.NewSpan() span.Attributes().PutStr("type", "mobile") return span }(), - config: config.Enabled(), + config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ elasticattr.TimestampUs: int64(0), elasticattr.TransactionSampled: true, @@ -492,19 +451,19 @@ func TestElasticTransactionEnrichWithType(t *testing.T) { }, }, { - name: "all_disabled", + name: "all_disabled_for_mobile", input: getElasticMobileTxn(), enrichedAttrs: map[string]any{}, }, { - name: "http_status_ok", + name: "http_status_ok_for_mobile", input: func() ptrace.Span { span := getElasticMobileTxn() span.SetName("testtxn") span.Attributes().PutInt(semconv25.AttributeHTTPStatusCode, http.StatusOK) return span }(), - config: config.Enabled(), + config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ elasticattr.TimestampUs: startTs.AsTime().UnixMicro(), elasticattr.TransactionSampled: true, @@ -520,6 +479,51 @@ func TestElasticTransactionEnrichWithType(t *testing.T) { elasticattr.TransactionType: "mobile", }, }, + } { + t.Run(tc.name, func(t *testing.T) { + expectedSpan := ptrace.NewSpan() + tc.input.CopyTo(expectedSpan) + + // Merge with the expected attributes and override the span links. + for k, v := range tc.enrichedAttrs { + expectedSpan.Attributes().PutEmpty(k).FromRaw(v) + } + // Override span links + if tc.expectedSpanLinks != nil { + tc.expectedSpanLinks.CopyTo(expectedSpan.Links()) + } else { + expectedSpan.Links().RemoveIf(func(_ ptrace.SpanLink) bool { return true }) + } + + EnrichSpan(tc.input, config.Config{ + Transaction: tc.config, + }, uaparser.NewFromSaved()) + assert.NoError(t, ptracetest.CompareSpan(expectedSpan, tc.input)) + }) + } +} + +// Tests the enrichment logic for elastic's transaction definition with type. +func TestElasticTransactionEnrichWithType(t *testing.T) { + now := time.Unix(3600, 0) + expectedDuration := time.Minute + endTs := pcommon.NewTimestampFromTime(now) + startTs := pcommon.NewTimestampFromTime(now.Add(-1 * expectedDuration)) + getElasticMobileTxn := func() ptrace.Span { + span := ptrace.NewSpan() + span.SetSpanID([8]byte{1}) + span.SetStartTimestamp(startTs) + span.SetEndTimestamp(endTs) + span.Attributes().PutStr("type", "mobile") + return span + } + for _, tc := range []struct { + name string + input ptrace.Span + config config.Config + enrichedAttrs map[string]any + expectedSpanLinks *ptrace.SpanLinkSlice + }{ { name: "outgoing_http_root_span", input: func() ptrace.Span { @@ -737,6 +741,44 @@ func TestRootSpanAsDependencyEnrich(t *testing.T) { elasticattr.SpanRepresentativeCount: float64(1), }, }, + { + name: "outgoing_mobile_http_root_span", + input: func() ptrace.Span { + span := ptrace.NewSpan() + span.SetName("rootClientSpan") + span.SetSpanID([8]byte{1}) + span.SetKind(ptrace.SpanKindClient) + span.Attributes().PutStr("type", "mobile") + span.Attributes().PutStr(semconv27.AttributeHTTPRequestMethod, "GET") + span.Attributes().PutStr(semconv27.AttributeURLFull, "http://localhost:8080") + span.Attributes().PutInt(semconv27.AttributeHTTPResponseStatusCode, 200) + span.Attributes().PutStr(semconv27.AttributeNetworkProtocolVersion, "1.1") + return span + }(), + config: config.Enabled(), + enrichedAttrs: map[string]any{ + elasticattr.TimestampUs: int64(0), + elasticattr.TransactionName: "rootClientSpan", + elasticattr.ProcessorEvent: "transaction", + elasticattr.SpanType: "external", + elasticattr.SpanSubtype: "http", + elasticattr.SpanDestinationServiceResource: "localhost:8080", + elasticattr.SpanName: "rootClientSpan", + elasticattr.EventOutcome: "success", + elasticattr.SuccessCount: int64(1), + elasticattr.ServiceTargetName: "localhost:8080", + elasticattr.ServiceTargetType: "http", + elasticattr.TransactionID: "0100000000000000", + elasticattr.TransactionDurationUs: int64(0), + elasticattr.TransactionRepresentativeCount: float64(1), + elasticattr.TransactionResult: "HTTP 2xx", + elasticattr.TransactionType: "mobile", + elasticattr.TransactionSampled: true, + elasticattr.TransactionRoot: true, + elasticattr.SpanDurationUs: int64(0), + elasticattr.SpanRepresentativeCount: float64(1), + }, + }, } { t.Run(tc.name, func(t *testing.T) { expectedSpan := ptrace.NewSpan() From ca781760d26e87a039ace6680f157136e753182e Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 25 Apr 2025 12:32:37 +0200 Subject: [PATCH 10/10] Clean up --- .../trace/internal/elastic/span_test.go | 79 ------------------- 1 file changed, 79 deletions(-) diff --git a/enrichments/trace/internal/elastic/span_test.go b/enrichments/trace/internal/elastic/span_test.go index ffe9357..9cddc02 100644 --- a/enrichments/trace/internal/elastic/span_test.go +++ b/enrichments/trace/internal/elastic/span_test.go @@ -503,85 +503,6 @@ func TestElasticTransactionEnrich(t *testing.T) { } } -// Tests the enrichment logic for elastic's transaction definition with type. -func TestElasticTransactionEnrichWithType(t *testing.T) { - now := time.Unix(3600, 0) - expectedDuration := time.Minute - endTs := pcommon.NewTimestampFromTime(now) - startTs := pcommon.NewTimestampFromTime(now.Add(-1 * expectedDuration)) - getElasticMobileTxn := func() ptrace.Span { - span := ptrace.NewSpan() - span.SetSpanID([8]byte{1}) - span.SetStartTimestamp(startTs) - span.SetEndTimestamp(endTs) - span.Attributes().PutStr("type", "mobile") - return span - } - for _, tc := range []struct { - name string - input ptrace.Span - config config.Config - enrichedAttrs map[string]any - expectedSpanLinks *ptrace.SpanLinkSlice - }{ - { - name: "outgoing_http_root_span", - input: func() ptrace.Span { - span := getElasticMobileTxn() - span.SetName("rootClientSpan") - span.SetKind(ptrace.SpanKindClient) - span.Attributes().PutStr(semconv27.AttributeHTTPRequestMethod, "GET") - span.Attributes().PutStr(semconv27.AttributeURLFull, "http://localhost:8080") - span.Attributes().PutInt(semconv27.AttributeHTTPResponseStatusCode, 200) - span.Attributes().PutStr(semconv27.AttributeNetworkProtocolVersion, "1.1") - return span - }(), - config: config.Enabled(), - enrichedAttrs: map[string]any{ - elasticattr.TimestampUs: startTs.AsTime().UnixMicro(), - elasticattr.TransactionName: "rootClientSpan", - elasticattr.ProcessorEvent: "transaction", - elasticattr.SpanType: "external", - elasticattr.SpanSubtype: "http", - elasticattr.SpanDestinationServiceResource: "localhost:8080", - elasticattr.SpanName: "rootClientSpan", - elasticattr.EventOutcome: "success", - elasticattr.SuccessCount: int64(1), - elasticattr.ServiceTargetName: "localhost:8080", - elasticattr.ServiceTargetType: "http", - elasticattr.TransactionID: "0100000000000000", - elasticattr.TransactionDurationUs: expectedDuration.Microseconds(), - elasticattr.TransactionRepresentativeCount: float64(1), - elasticattr.TransactionResult: "HTTP 2xx", - elasticattr.TransactionType: "mobile", - elasticattr.TransactionSampled: true, - elasticattr.TransactionRoot: true, - elasticattr.SpanDurationUs: expectedDuration.Microseconds(), - elasticattr.SpanRepresentativeCount: float64(1), - }, - }, - } { - t.Run(tc.name, func(t *testing.T) { - expectedSpan := ptrace.NewSpan() - tc.input.CopyTo(expectedSpan) - - // Merge with the expected attributes and override the span links. - for k, v := range tc.enrichedAttrs { - expectedSpan.Attributes().PutEmpty(k).FromRaw(v) - } - // Override span links - if tc.expectedSpanLinks != nil { - tc.expectedSpanLinks.CopyTo(expectedSpan.Links()) - } else { - expectedSpan.Links().RemoveIf(func(_ ptrace.SpanLink) bool { return true }) - } - - EnrichSpan(tc.input, tc.config, uaparser.NewFromSaved()) - assert.NoError(t, ptracetest.CompareSpan(expectedSpan, tc.input)) - }) - } -} - // Tests root spans that represent a dependency and are mapped to a transaction. func TestRootSpanAsDependencyEnrich(t *testing.T) { for _, tc := range []struct {