From ac2c3a51d5f9d539ebdb208da02dc6775c5f38b3 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 22 May 2026 17:37:47 +0200 Subject: [PATCH] span compression: do not consider canceled span available for compression Should hopefully fix kafka flaky tests. Assisted-by: Cursor --- elasticapm/traces.py | 7 +++- .../transactions_store_tests.py | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/elasticapm/traces.py b/elasticapm/traces.py index 929458d7a..8a8939b9c 100644 --- a/elasticapm/traces.py +++ b/elasticapm/traces.py @@ -668,7 +668,12 @@ def is_compression_eligible(self) -> bool: Determine if this span is eligible for compression. """ if self.transaction.config_span_compression_enabled: - return self.leaf and not self.dist_tracing_propagated and self.outcome in (None, constants.OUTCOME.SUCCESS) + return ( + self.leaf + and not self._cancelled + and not self.dist_tracing_propagated + and self.outcome in (None, constants.OUTCOME.SUCCESS) + ) return False @property diff --git a/tests/instrumentation/transactions_store_tests.py b/tests/instrumentation/transactions_store_tests.py index 23a8d0b2a..111c3b0c6 100644 --- a/tests/instrumentation/transactions_store_tests.py +++ b/tests/instrumentation/transactions_store_tests.py @@ -204,6 +204,48 @@ def test_leaf_tracing(tracer): assert {t["name"] for t in spans} == signatures +def test_cancelled_spans_do_not_compress_with_later_spans(elasticapm_client): + elasticapm_client.config.update( + "1", + span_compression_enabled=True, + span_compression_exact_match_max_duration="50ms", + span_compression_same_kind_max_duration="50ms", + ) + elasticapm_client.begin_transaction("transaction.test") + + extra = { + "message": {"queue": {"name": "topic"}}, + "destination": {"service": {"name": "kafka", "resource": "kafka/topic", "type": "messaging"}}, + } + with capture_span( + "Kafka RECEIVE from topic", + span_type="messaging", + span_subtype="kafka", + span_action="receive", + extra=extra.copy(), + leaf=True, + duration=0.01, + ) as span: + span.cancel() + + with capture_span( + "Kafka RECEIVE from topic", + span_type="messaging", + span_subtype="kafka", + span_action="receive", + extra=extra.copy(), + leaf=True, + duration=0.01, + ): + pass + + elasticapm_client.end_transaction("transaction") + + spans = elasticapm_client.events[SPAN] + assert len(spans) == 1 + assert spans[0]["name"] == "Kafka RECEIVE from topic" + + def test_get_trace_parent_header(elasticapm_client): trace_parent = TraceParent.from_string("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03") transaction = elasticapm_client.begin_transaction("test", trace_parent=trace_parent)