From 7298b08717c19dab2ca75537e1de7a3866f7ef53 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 7 Sep 2026 14:01:53 +0200 Subject: [PATCH] chore(gcp): Remove transaction-based tracing --- sentry_sdk/integrations/gcp.py | 49 +++----- tests/integrations/gcp/test_gcp.py | 194 +++-------------------------- 2 files changed, 34 insertions(+), 209 deletions(-) diff --git a/sentry_sdk/integrations/gcp.py b/sentry_sdk/integrations/gcp.py index 170b31c9d5..bbddbdc53a 100644 --- a/sentry_sdk/integrations/gcp.py +++ b/sentry_sdk/integrations/gcp.py @@ -6,7 +6,6 @@ from typing import TYPE_CHECKING import sentry_sdk -from sentry_sdk.api import continue_trace from sentry_sdk.consts import OP from sentry_sdk.data_collection import _apply_data_collection_filtering_to_query_string from sentry_sdk.integrations import Integration @@ -14,8 +13,6 @@ from sentry_sdk.integrations.cloud_resource_context import CLOUD_PROVIDER from sentry_sdk.scope import Scope, should_send_default_pii from sentry_sdk.traces import SegmentNameSource -from sentry_sdk.tracing import TransactionSource -from sentry_sdk.tracing_utils import has_span_streaming_enabled from sentry_sdk.utils import ( AnnotatedValue, TimeoutThread, @@ -140,36 +137,22 @@ def sentry_func( if environ.get("ENTRY_POINT"): additional_attributes["faas.entry_point"] = environ.get("ENTRY_POINT") - if has_span_streaming_enabled(client.options): - sentry_sdk.traces.continue_trace(headers) - Scope.set_custom_sampling_context(sampling_context) - span_ctx = sentry_sdk.traces.start_span( - name=function_name, - parent_span=None, - attributes={ - "sentry.op": OP.FUNCTION_GCP, - "sentry.origin": GcpIntegration.origin, - "sentry.segment.name.source": SegmentNameSource.COMPONENT, - "cloud.provider": CLOUD_PROVIDER.GCP, - "faas.name": function_name, - **header_attributes, - **additional_attributes, - }, - ) - else: - transaction = continue_trace( - headers, - op=OP.FUNCTION_GCP, - name=environ.get("FUNCTION_NAME", ""), - source=TransactionSource.COMPONENT, - origin=GcpIntegration.origin, - ) - - span_ctx = sentry_sdk.start_transaction( - transaction, custom_sampling_context=sampling_context - ) - - with span_ctx: + sentry_sdk.traces.continue_trace(headers) + Scope.set_custom_sampling_context(sampling_context) + + with sentry_sdk.traces.start_span( + name=function_name, + parent_span=None, + attributes={ + "sentry.op": OP.FUNCTION_GCP, + "sentry.origin": GcpIntegration.origin, + "sentry.segment.name.source": SegmentNameSource.COMPONENT, + "cloud.provider": CLOUD_PROVIDER.GCP, + "faas.name": function_name, + **header_attributes, + **additional_attributes, + }, + ): try: return func(functionhandler, gcp_event, *args, **kwargs) except Exception: diff --git a/tests/integrations/gcp/test_gcp.py b/tests/integrations/gcp/test_gcp.py index 52496ad378..c533eddb24 100644 --- a/tests/integrations/gcp/test_gcp.py +++ b/tests/integrations/gcp/test_gcp.py @@ -238,65 +238,6 @@ def cloud_function(functionhandler, event): assert envelope_items[0]["tags"]["cloud_function"] == "true" -def test_performance_no_error(run_cloud_function): - envelope_items, _, _ = run_cloud_function( - dedent( - """ - functionhandler = None - event = {} - def cloud_function(functionhandler, event): - return "test_string" - """ - ) - + FUNCTIONS_PRELUDE - + dedent( - """ - init_sdk(traces_sample_rate=1.0) - gcp_functions.worker_v1.FunctionHandler.invoke_user_function(functionhandler, event) - """ - ) - ) - - assert envelope_items[0]["type"] == "transaction" - assert envelope_items[0]["contexts"]["trace"]["op"] == "function.gcp" - assert envelope_items[0]["transaction"].startswith("Google Cloud function") - assert envelope_items[0]["transaction_info"] == {"source": "component"} - assert envelope_items[0]["transaction"] in envelope_items[0]["request"]["url"] - - -def test_performance_error(run_cloud_function): - envelope_items, _, _ = run_cloud_function( - dedent( - """ - functionhandler = None - event = {} - def cloud_function(functionhandler, event): - raise Exception("something went wrong") - """ - ) - + FUNCTIONS_PRELUDE - + dedent( - """ - init_sdk(traces_sample_rate=1.0) - gcp_functions.worker_v1.FunctionHandler.invoke_user_function(functionhandler, event) - """ - ) - ) - - assert envelope_items[0]["level"] == "error" - (exception,) = envelope_items[0]["exception"]["values"] - - assert exception["type"] == "Exception" - assert exception["value"] == "something went wrong" - assert exception["mechanism"]["type"] == "gcp" - assert not exception["mechanism"]["handled"] - - assert envelope_items[1]["type"] == "transaction" - assert envelope_items[1]["contexts"]["trace"]["op"] == "function.gcp" - assert envelope_items[1]["transaction"].startswith("Google Cloud function") - assert envelope_items[1]["transaction"] in envelope_items[0]["request"]["url"] - - def test_traces_sampler_gets_correct_values_in_sampling_context( run_cloud_function, DictionaryContaining, # noqa:N803 @@ -367,6 +308,7 @@ def _safe_is_equal(x, y): init_sdk( traces_sampler=traces_sampler, + trace_lifecycle="stream", ) gcp_functions.worker_v1.FunctionHandler.invoke_user_function(functionhandler, event) @@ -379,9 +321,9 @@ def _safe_is_equal(x, y): def test_error_has_new_trace_context_performance_enabled(run_cloud_function): """ - Check if an 'trace' context is added to errros and transactions when performance monitoring is enabled. + Check if a 'trace' context is added to errors and spans when performance monitoring is enabled. """ - envelope_items, _, _ = run_cloud_function( + envelope_items, _, span_items = run_cloud_function( dedent( """ functionhandler = None @@ -395,12 +337,12 @@ def cloud_function(functionhandler, event): + FUNCTIONS_PRELUDE + dedent( """ - init_sdk(traces_sample_rate=1.0) + init_sdk(traces_sample_rate=1.0, trace_lifecycle="stream") gcp_functions.worker_v1.FunctionHandler.invoke_user_function(functionhandler, event) """ ) ) - (msg_event, error_event, transaction_event) = envelope_items + (msg_event, error_event) = envelope_items assert "trace" in msg_event["contexts"] assert "trace_id" in msg_event["contexts"]["trace"] @@ -408,13 +350,13 @@ def cloud_function(functionhandler, event): assert "trace" in error_event["contexts"] assert "trace_id" in error_event["contexts"]["trace"] - assert "trace" in transaction_event["contexts"] - assert "trace_id" in transaction_event["contexts"]["trace"] + assert len(span_items) == 1 + segment_span = span_items[0] assert ( msg_event["contexts"]["trace"]["trace_id"] == error_event["contexts"]["trace"]["trace_id"] - == transaction_event["contexts"]["trace"]["trace_id"] + == segment_span["trace_id"] ) @@ -456,59 +398,6 @@ def cloud_function(functionhandler, event): ) -def test_error_has_existing_trace_context_performance_enabled(run_cloud_function): - """ - Check if an 'trace' context is added to errros and transactions - from the incoming 'sentry-trace' header when performance monitoring is enabled. - """ - trace_id = "471a43a4192642f0b136d5159a501701" - parent_span_id = "6e8f22c393e68f19" - parent_sampled = 1 - sentry_trace_header = "{}-{}-{}".format(trace_id, parent_span_id, parent_sampled) - - envelope_items, _, _ = run_cloud_function( - dedent( - """ - functionhandler = None - - from collections import namedtuple - GCPEvent = namedtuple("GCPEvent", ["headers"]) - event = GCPEvent(headers={"sentry-trace": "%s"}) - - def cloud_function(functionhandler, event): - sentry_sdk.capture_message("hi") - x = 3/0 - return "3" - """ - % sentry_trace_header - ) - + FUNCTIONS_PRELUDE - + dedent( - """ - init_sdk(traces_sample_rate=1.0) - gcp_functions.worker_v1.FunctionHandler.invoke_user_function(functionhandler, event) - """ - ) - ) - (msg_event, error_event, transaction_event) = envelope_items - - assert "trace" in msg_event["contexts"] - assert "trace_id" in msg_event["contexts"]["trace"] - - assert "trace" in error_event["contexts"] - assert "trace_id" in error_event["contexts"]["trace"] - - assert "trace" in transaction_event["contexts"] - assert "trace_id" in transaction_event["contexts"]["trace"] - - assert ( - msg_event["contexts"]["trace"]["trace_id"] - == error_event["contexts"]["trace"]["trace_id"] - == transaction_event["contexts"]["trace"]["trace_id"] - == "471a43a4192642f0b136d5159a501701" - ) - - def test_error_has_existing_trace_context_performance_disabled(run_cloud_function): """ Check if an 'trace' context is added to errros and transactions @@ -559,7 +448,7 @@ def cloud_function(functionhandler, event): def test_span_origin(run_cloud_function): - events, _, _ = run_cloud_function( + _, _, span_items = run_cloud_function( dedent( """ functionhandler = None @@ -571,18 +460,17 @@ def cloud_function(functionhandler, event): + FUNCTIONS_PRELUDE + dedent( """ - init_sdk(traces_sample_rate=1.0) + init_sdk(traces_sample_rate=1.0, trace_lifecycle="stream") gcp_functions.worker_v1.FunctionHandler.invoke_user_function(functionhandler, event) """ ) ) - (event,) = events - - assert event["contexts"]["trace"]["origin"] == "auto.function.gcp" + assert len(span_items) == 1 + assert span_items[0]["attributes"]["sentry.origin"] == "auto.function.gcp" -def test_span_streaming_no_error(run_cloud_function): +def test_performance_no_error(run_cloud_function): _, _, span_items = run_cloud_function( dedent( """ @@ -616,7 +504,7 @@ def cloud_function(functionhandler, event): assert segment_span["attributes"]["faas.entry_point"] == "cloud_function" -def test_span_streaming_error(run_cloud_function): +def test_performance_error(run_cloud_function): envelope_items, _, span_items = run_cloud_function( dedent( """ @@ -657,7 +545,7 @@ def cloud_function(functionhandler, event): assert segment_span["status"] == SpanStatus.ERROR -def test_span_streaming_existing_trace_context(run_cloud_function): +def test_existing_trace_context(run_cloud_function): trace_id = "471a43a4192642f0b136d5159a501701" parent_span_id = "6e8f22c393e68f19" parent_sampled = 1 @@ -705,7 +593,7 @@ def cloud_function(functionhandler, event): assert segment_span["attributes"]["faas.entry_point"] == "cloud_function" -def test_span_streaming_request_attributes(run_cloud_function): +def test_request_attributes(run_cloud_function): _, _, span_items = run_cloud_function( dedent( """ @@ -746,7 +634,7 @@ def cloud_function(functionhandler, event): assert attrs["faas.entry_point"] == "cloud_function" -def test_span_streaming_no_query_string_without_pii(run_cloud_function): +def test_no_query_string_without_pii(run_cloud_function): _, _, span_items = run_cloud_function( dedent( """ @@ -863,53 +751,7 @@ def _build_init_kwargs(send_default_pii, data_collection): "send_default_pii, data_collection, expected_event, expected_span", _QUERY_STRING_DATA_COLLECTION_CASES, ) -def test_query_string_data_collection_event_processor( - run_cloud_function, - send_default_pii, - data_collection, - expected_event, - expected_span, -): - init_kwargs = _build_init_kwargs(send_default_pii, data_collection) - envelope_items, _, _ = run_cloud_function( - dedent( - """ - functionhandler = None - - from collections import namedtuple - GCPEvent = namedtuple("GCPEvent", ["headers", "method", "query_string"]) - event = GCPEvent( - headers={}, - method="GET", - query_string=b"toy=tennisball&color=red&auth=secret", - ) - - def cloud_function(functionhandler, event): - raise Exception("something went wrong") - """ - ) - + FUNCTIONS_PRELUDE - + dedent( - """ - init_sdk(%s) - gcp_functions.worker_v1.FunctionHandler.invoke_user_function(functionhandler, event) - """ - % init_kwargs - ) - ) - - request = envelope_items[0]["request"] - if expected_event is None: - assert "query_string" not in request - else: - assert request["query_string"] == expected_event - - -@pytest.mark.parametrize( - "send_default_pii, data_collection, expected_event, expected_span", - _QUERY_STRING_DATA_COLLECTION_CASES, -) -def test_query_string_data_collection_span_streaming( +def test_query_string_data_collection( run_cloud_function, send_default_pii, data_collection,