From d3d6e04dfc3d9172b183508305411f8590c64bd9 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 5 Jun 2026 14:03:54 +0200 Subject: [PATCH 1/3] feat(clickhouse_driver): Support span streaming --- sentry_sdk/integrations/clickhouse_driver.py | 79 +- .../test_clickhouse_driver.py | 1407 +++++++++++------ 2 files changed, 1019 insertions(+), 467 deletions(-) diff --git a/sentry_sdk/integrations/clickhouse_driver.py b/sentry_sdk/integrations/clickhouse_driver.py index ede9ed8a06..2acef16f42 100644 --- a/sentry_sdk/integrations/clickhouse_driver.py +++ b/sentry_sdk/integrations/clickhouse_driver.py @@ -4,15 +4,17 @@ from sentry_sdk.consts import OP, SPANDATA from sentry_sdk.integrations import DidNotEnable, Integration, _check_minimum_version from sentry_sdk.scope import should_send_default_pii +from sentry_sdk.traces import StreamedSpan from sentry_sdk.tracing import Span -from sentry_sdk.utils import capture_internal_exceptions, ensure_integration_enabled +from sentry_sdk.tracing_utils import has_span_streaming_enabled +from sentry_sdk.utils import capture_internal_exceptions # Hack to get new Python features working in older versions # without introducing a hard dependency on `typing_extensions` # from: https://stackoverflow.com/a/71944042/300572 if TYPE_CHECKING: from collections.abc import Iterator - from typing import Any, Callable, ParamSpec + from typing import Any, Callable, ParamSpec, Union else: # Fake ParamSpec class ParamSpec: @@ -70,30 +72,42 @@ def setup_once() -> None: def _wrap_start(f: "Callable[P, T]") -> "Callable[P, T]": - @ensure_integration_enabled(ClickhouseDriverIntegration, f) def _inner(*args: "P.args", **kwargs: "P.kwargs") -> "T": + client = sentry_sdk.get_client() + if client.get_integration(ClickhouseDriverIntegration) is None: + return f(*args, **kwargs) + connection = args[0] query = args[1] query_id = args[2] if len(args) > 2 else kwargs.get("query_id") params = args[3] if len(args) > 3 else kwargs.get("params") - span = sentry_sdk.start_span( - op=OP.DB, - name=query, - origin=ClickhouseDriverIntegration.origin, - ) + if has_span_streaming_enabled(client.options): + span = sentry_sdk.traces.start_span( + name=query, + attributes={ + "sentry.op": OP.DB, + "sentry.origin": ClickhouseDriverIntegration.origin, + }, + ) + else: + span = sentry_sdk.start_span( + op=OP.DB, + name=query, + origin=ClickhouseDriverIntegration.origin, + ) - connection._sentry_span = span # type: ignore[attr-defined] + span.set_data("query", query) - _set_db_data(span, connection) + if query_id: + span.set_data("db.query_id", query_id) - span.set_data("query", query) + if params and should_send_default_pii(): + span.set_data("db.params", params) - if query_id: - span.set_data("db.query_id", query_id) + connection._sentry_span = span # type: ignore[attr-defined] - if params and should_send_default_pii(): - span.set_data("db.params", params) + _set_db_data(span, connection) # run the original code ret = f(*args, **kwargs) @@ -109,7 +123,12 @@ def _inner_end(*args: "P.args", **kwargs: "P.kwargs") -> "T": instance = args[0] span = getattr(instance.connection, "_sentry_span", None) # type: ignore[attr-defined] - if span is not None: + if span is None: + return res + + if isinstance(span, StreamedSpan): + span.end() + else: if res is not None and should_send_default_pii(): span.set_data("db.result", res) @@ -133,6 +152,12 @@ def _inner_send_data( # type: ignore[no-untyped-def] # clickhouse-driver does n ): span = getattr(self.connection, "_sentry_span", None) + if isinstance(span, StreamedSpan): + _set_db_data(span, self.connection) + return original_send_data( + self, sample_block, data, types_check, columnar, *args, **kwargs + ) + if span is not None: _set_db_data(span, self.connection) @@ -165,10 +190,18 @@ def wrapped_generator() -> "Iterator[Any]": Client.send_data = _inner_send_data -def _set_db_data(span: "Span", connection: "Connection") -> None: - span.set_data(SPANDATA.DB_SYSTEM, "clickhouse") - span.set_data(SPANDATA.DB_DRIVER_NAME, "clickhouse-driver") - span.set_data(SPANDATA.SERVER_ADDRESS, connection.host) - span.set_data(SPANDATA.SERVER_PORT, connection.port) - span.set_data(SPANDATA.DB_NAME, connection.database) - span.set_data(SPANDATA.DB_USER, connection.user) +def _set_db_data(span: "Union[Span, StreamedSpan]", connection: "Connection") -> None: + if isinstance(span, StreamedSpan): + span.set_attribute(SPANDATA.DB_SYSTEM, "clickhouse") + span.set_attribute(SPANDATA.DB_DRIVER_NAME, "clickhouse-driver") + span.set_attribute(SPANDATA.SERVER_ADDRESS, connection.host) + span.set_attribute(SPANDATA.SERVER_PORT, connection.port) + span.set_attribute(SPANDATA.DB_NAME, connection.database) + span.set_attribute(SPANDATA.DB_USER, connection.user) + else: + span.set_data(SPANDATA.DB_SYSTEM, "clickhouse") + span.set_data(SPANDATA.DB_DRIVER_NAME, "clickhouse-driver") + span.set_data(SPANDATA.SERVER_ADDRESS, connection.host) + span.set_data(SPANDATA.SERVER_PORT, connection.port) + span.set_data(SPANDATA.DB_NAME, connection.database) + span.set_data(SPANDATA.DB_USER, connection.user) diff --git a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py index b81f05e04c..de8a5a1f00 100644 --- a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py +++ b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py @@ -5,9 +5,13 @@ ``` """ +from unittest import mock + import clickhouse_driver +import pytest from clickhouse_driver import Client, connect +import sentry_sdk from sentry_sdk import capture_message, start_transaction from sentry_sdk.integrations.clickhouse_driver import ClickhouseDriverIntegration from tests.conftest import ApproxDict @@ -225,131 +229,258 @@ def test_clickhouse_client_breadcrumbs_with_pii(sentry_init, capture_events) -> assert event["breadcrumbs"]["values"] == expected_breadcrumbs +@pytest.mark.parametrize("span_streaming", [True, False]) def test_clickhouse_client_spans( - sentry_init, capture_events, capture_envelopes -) -> None: + sentry_init, + capture_events, + capture_items, + capture_envelopes, + span_streaming, +): sentry_init( integrations=[ClickhouseDriverIntegration()], - _experiments={"record_sql_params": True}, + _experiments={ + "record_sql_params": True, + "trace_lifecycle": "stream" if span_streaming else "static", + }, traces_sample_rate=1.0, ) - events = capture_events() - - transaction_trace_id = None - transaction_span_id = None - - with start_transaction(name="test_clickhouse_transaction") as transaction: - transaction_trace_id = transaction.trace_id - transaction_span_id = transaction.span_id - - client = Client("localhost") - client.execute("DROP TABLE IF EXISTS test") - client.execute("CREATE TABLE test (x Int32) ENGINE = Memory") - client.execute("INSERT INTO test (x) VALUES", [{"x": 100}]) - client.execute("INSERT INTO test (x) VALUES", [[170], [200]]) - - res = client.execute( - "SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150} - ) - assert res[0][0] == 370 - - (event,) = events - - expected_spans = [ - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "DROP TABLE IF EXISTS test", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + if span_streaming: + items = capture_items("span") + + trace_id = None + span_id = None + + with sentry_sdk.traces.start_span(name="custom parent") as span: + trace_id = span.trace_id + span_id = span.span_id + + client = Client("localhost") + client.execute("DROP TABLE IF EXISTS test") + client.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + client.execute("INSERT INTO test (x) VALUES", [{"x": 100}]) + client.execute("INSERT INTO test (x) VALUES", [[170], [200]]) + + res = client.execute( + "SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150} + ) + assert res[0][0] == 370 + + sentry_sdk.flush() + spans = [item.payload for item in items if item.type == "span"] + + expected_spans = [ + { + "name": "DROP TABLE IF EXISTS test", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "CREATE TABLE test (x Int32) ENGINE = Memory", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "name": "CREATE TABLE test (x Int32) ENGINE = Memory", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "SELECT sum(x) FROM test WHERE x > 150", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "name": "SELECT sum(x) FROM test WHERE x > 150", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - ] + { + "name": "custom parent", + "attributes": [], + "trace_id": trace_id, + }, + ] + + for span in expected_spans: + span["attributes"] = ApproxDict(span["attributes"]) + + for span in spans: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("end_timestamp", None) + span.pop("is_segment", None) + span.pop("status", None) + + assert spans == expected_spans + else: + events = capture_events() + + transaction_trace_id = None + transaction_span_id = None + + with start_transaction(name="test_clickhouse_transaction") as transaction: + transaction_trace_id = transaction.trace_id + transaction_span_id = transaction.span_id + + client = Client("localhost") + client.execute("DROP TABLE IF EXISTS test") + client.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + client.execute("INSERT INTO test (x) VALUES", [{"x": 100}]) + client.execute("INSERT INTO test (x) VALUES", [[170], [200]]) + + res = client.execute( + "SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150} + ) + assert res[0][0] == 370 + + (event,) = events + + expected_spans = [ + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "DROP TABLE IF EXISTS test", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "CREATE TABLE test (x Int32) ENGINE = Memory", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "SELECT sum(x) FROM test WHERE x > 150", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + ] - if not EXPECT_PARAMS_IN_SELECT: - expected_spans[-1]["data"].pop("db.params", None) + if not EXPECT_PARAMS_IN_SELECT: + expected_spans[-1]["data"].pop("db.params", None) - for span in expected_spans: - span["data"] = ApproxDict(span["data"]) + for span in expected_spans: + span["data"] = ApproxDict(span["data"]) - for span in event["spans"]: - span.pop("span_id", None) - span.pop("start_timestamp", None) - span.pop("timestamp", None) + for span in event["spans"]: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("timestamp", None) - assert event["spans"] == expected_spans + assert event["spans"] == expected_spans def test_clickhouse_spans_with_generator(sentry_init, capture_events): @@ -384,133 +515,251 @@ def test_clickhouse_spans_with_generator(sentry_init, capture_events): assert span["data"]["db.params"] == [{"x": 0}, {"x": 1}, {"x": 2}] +@pytest.mark.parametrize("span_streaming", [True, False]) def test_clickhouse_client_spans_with_pii( - sentry_init, capture_events, capture_envelopes -) -> None: + sentry_init, + capture_events, + capture_items, + capture_envelopes, + span_streaming, +): sentry_init( integrations=[ClickhouseDriverIntegration()], - _experiments={"record_sql_params": True}, + _experiments={ + "record_sql_params": True, + "trace_lifecycle": "stream" if span_streaming else "static", + }, traces_sample_rate=1.0, send_default_pii=True, ) - events = capture_events() - - transaction_trace_id = None - transaction_span_id = None - - with start_transaction(name="test_clickhouse_transaction") as transaction: - transaction_trace_id = transaction.trace_id - transaction_span_id = transaction.span_id - - client = Client("localhost") - client.execute("DROP TABLE IF EXISTS test") - client.execute("CREATE TABLE test (x Int32) ENGINE = Memory") - client.execute("INSERT INTO test (x) VALUES", [{"x": 100}]) - client.execute("INSERT INTO test (x) VALUES", [[170], [200]]) - - res = client.execute( - "SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150} - ) - assert res[0][0] == 370 - - (event,) = events - - expected_spans = [ - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "DROP TABLE IF EXISTS test", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.result": [], + if span_streaming: + items = capture_items("span") + + trace_id = None + span_id = None + + with sentry_sdk.traces.start_span(name="custom parent") as span: + trace_id = span.trace_id + span_id = span.span_id + + client = Client("localhost") + client.execute("DROP TABLE IF EXISTS test") + client.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + client.execute("INSERT INTO test (x) VALUES", [{"x": 100}]) + client.execute("INSERT INTO test (x) VALUES", [[170], [200]]) + + res = client.execute( + "SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150} + ) + assert res[0][0] == 370 + + sentry_sdk.flush() + spans = [item.payload for item in items if item.type == "span"] + + expected_spans = [ + { + "name": "DROP TABLE IF EXISTS test", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "thread.id": mock.ANY, + "thread.name": mock.ANY, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "CREATE TABLE test (x Int32) ENGINE = Memory", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.result": [], + { + "name": "CREATE TABLE test (x Int32) ENGINE = Memory", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "thread.id": mock.ANY, + "thread.name": mock.ANY, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.params": [{"x": 100}], + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "thread.id": mock.ANY, + "thread.name": mock.ANY, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.params": [[170], [200]], + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "SELECT sum(x) FROM test WHERE x > 150", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.params": {"minv": 150}, - "db.result": [[370]], + { + "name": "SELECT sum(x) FROM test WHERE x > 150", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - ] + { + "name": "custom parent", + "attributes": [], + "trace_id": trace_id, + }, + ] + + for span in expected_spans: + span["attributes"] = ApproxDict(span["attributes"]) + + for span in spans: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("end_timestamp", None) + span.pop("is_segment", None) + span.pop("status", None) + + assert spans == expected_spans + else: + events = capture_events() + + transaction_trace_id = None + transaction_span_id = None + + with start_transaction(name="test_clickhouse_transaction") as transaction: + transaction_trace_id = transaction.trace_id + transaction_span_id = transaction.span_id + + client = Client("localhost") + client.execute("DROP TABLE IF EXISTS test") + client.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + client.execute("INSERT INTO test (x) VALUES", [{"x": 100}]) + client.execute("INSERT INTO test (x) VALUES", [[170], [200]]) + + res = client.execute( + "SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150} + ) + assert res[0][0] == 370 + + (event,) = events + + expected_spans = [ + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "DROP TABLE IF EXISTS test", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.result": [], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "CREATE TABLE test (x Int32) ENGINE = Memory", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.result": [], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.params": [{"x": 100}], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.params": [[170], [200]], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "SELECT sum(x) FROM test WHERE x > 150", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.params": {"minv": 150}, + "db.result": [[370]], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, + }, + ] - if not EXPECT_PARAMS_IN_SELECT: - expected_spans[-1]["data"].pop("db.params", None) + if not EXPECT_PARAMS_IN_SELECT: + expected_spans[-1]["data"].pop("db.params", None) - for span in expected_spans: - span["data"] = ApproxDict(span["data"]) + for span in expected_spans: + span["data"] = ApproxDict(span["data"]) - for span in event["spans"]: - span.pop("span_id", None) - span.pop("start_timestamp", None) - span.pop("timestamp", None) + for span in event["spans"]: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("timestamp", None) - assert event["spans"] == expected_spans + assert event["spans"] == expected_spans def test_clickhouse_dbapi_breadcrumbs(sentry_init, capture_events) -> None: @@ -717,274 +966,544 @@ def test_clickhouse_dbapi_breadcrumbs_with_pii(sentry_init, capture_events) -> N assert event["breadcrumbs"]["values"] == expected_breadcrumbs -def test_clickhouse_dbapi_spans(sentry_init, capture_events, capture_envelopes) -> None: +@pytest.mark.parametrize("span_streaming", [True, False]) +def test_clickhouse_dbapi_spans( + sentry_init, + capture_events, + capture_items, + capture_envelopes, + span_streaming, +): sentry_init( integrations=[ClickhouseDriverIntegration()], - _experiments={"record_sql_params": True}, + _experiments={ + "record_sql_params": True, + "trace_lifecycle": "stream" if span_streaming else "static", + }, traces_sample_rate=1.0, ) - events = capture_events() - - transaction_trace_id = None - transaction_span_id = None - - with start_transaction(name="test_clickhouse_transaction") as transaction: - transaction_trace_id = transaction.trace_id - transaction_span_id = transaction.span_id - - conn = connect("clickhouse://localhost") - cursor = conn.cursor() - cursor.execute("DROP TABLE IF EXISTS test") - cursor.execute("CREATE TABLE test (x Int32) ENGINE = Memory") - cursor.executemany("INSERT INTO test (x) VALUES", [{"x": 100}]) - cursor.executemany("INSERT INTO test (x) VALUES", [[170], [200]]) - cursor.execute("SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150}) - res = cursor.fetchall() + if span_streaming: + items = capture_items("span") + + trace_id = None + span_id = None + + with sentry_sdk.traces.start_span(name="custom parent") as span: + trace_id = span.trace_id + span_id = span.span_id + + conn = connect("clickhouse://localhost") + cursor = conn.cursor() + cursor.execute("DROP TABLE IF EXISTS test") + cursor.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + cursor.executemany("INSERT INTO test (x) VALUES", [{"x": 100}]) + cursor.executemany("INSERT INTO test (x) VALUES", [[170], [200]]) + cursor.execute("SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150}) + res = cursor.fetchall() + + sentry_sdk.flush() + spans = [item.payload for item in items if item.type == "span"] + + expected_spans = [ + { + "name": "DROP TABLE IF EXISTS test", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "CREATE TABLE test (x Int32) ENGINE = Memory", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "SELECT sum(x) FROM test WHERE x > 150", + "attributes": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "custom parent", + "attributes": [], + "trace_id": trace_id, + }, + ] + + for span in expected_spans: + span["attributes"] = ApproxDict(span["attributes"]) + + for span in spans: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("end_timestamp", None) + span.pop("is_segment", None) + span.pop("status", None) + + assert spans == expected_spans + else: + events = capture_events() + + transaction_trace_id = None + transaction_span_id = None + + with start_transaction(name="test_clickhouse_transaction") as transaction: + transaction_trace_id = transaction.trace_id + transaction_span_id = transaction.span_id + + conn = connect("clickhouse://localhost") + cursor = conn.cursor() + cursor.execute("DROP TABLE IF EXISTS test") + cursor.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + cursor.executemany("INSERT INTO test (x) VALUES", [{"x": 100}]) + cursor.executemany("INSERT INTO test (x) VALUES", [[170], [200]]) + cursor.execute("SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150}) + res = cursor.fetchall() assert res[0][0] == 370 - (event,) = events - - expected_spans = [ - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "DROP TABLE IF EXISTS test", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + (event,) = events + + expected_spans = [ + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "DROP TABLE IF EXISTS test", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "CREATE TABLE test (x Int32) ENGINE = Memory", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "CREATE TABLE test (x Int32) ENGINE = Memory", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "SELECT sum(x) FROM test WHERE x > 150", - "data": { - "db.system": "clickhouse", - "db.driver.name": "clickhouse-driver", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "SELECT sum(x) FROM test WHERE x > 150", + "data": { + "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - ] + ] - if not EXPECT_PARAMS_IN_SELECT: - expected_spans[-1]["data"].pop("db.params", None) + if not EXPECT_PARAMS_IN_SELECT: + expected_spans[-1]["data"].pop("db.params", None) - for span in expected_spans: - span["data"] = ApproxDict(span["data"]) + for span in expected_spans: + span["data"] = ApproxDict(span["data"]) - for span in event["spans"]: - span.pop("span_id", None) - span.pop("start_timestamp", None) - span.pop("timestamp", None) + for span in event["spans"]: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("timestamp", None) - assert event["spans"] == expected_spans + assert event["spans"] == expected_spans +@pytest.mark.parametrize("span_streaming", [True, False]) def test_clickhouse_dbapi_spans_with_pii( - sentry_init, capture_events, capture_envelopes -) -> None: + sentry_init, + capture_events, + capture_items, + capture_envelopes, + span_streaming, +): sentry_init( integrations=[ClickhouseDriverIntegration()], - _experiments={"record_sql_params": True}, + _experiments={ + "record_sql_params": True, + "trace_lifecycle": "stream" if span_streaming else "static", + }, traces_sample_rate=1.0, send_default_pii=True, ) - events = capture_events() + if span_streaming: + items = capture_items("span") - transaction_trace_id = None - transaction_span_id = None + trace_id = None + span_id = None - with start_transaction(name="test_clickhouse_transaction") as transaction: - transaction_trace_id = transaction.trace_id - transaction_span_id = transaction.span_id + with sentry_sdk.traces.start_span(name="custom parent") as span: + trace_id = span.trace_id + span_id = span.span_id - conn = connect("clickhouse://localhost") - cursor = conn.cursor() - cursor.execute("DROP TABLE IF EXISTS test") - cursor.execute("CREATE TABLE test (x Int32) ENGINE = Memory") - cursor.executemany("INSERT INTO test (x) VALUES", [{"x": 100}]) - cursor.executemany("INSERT INTO test (x) VALUES", [[170], [200]]) - cursor.execute("SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150}) - res = cursor.fetchall() + conn = connect("clickhouse://localhost") + cursor = conn.cursor() + cursor.execute("DROP TABLE IF EXISTS test") + cursor.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + cursor.executemany("INSERT INTO test (x) VALUES", [{"x": 100}]) + cursor.executemany("INSERT INTO test (x) VALUES", [[170], [200]]) + cursor.execute("SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150}) + res = cursor.fetchall() assert res[0][0] == 370 - (event,) = events + sentry_sdk.flush() + spans = [item.payload for item in items if item.type == "span"] + + expected_spans = [ + { + "name": "DROP TABLE IF EXISTS test", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "CREATE TABLE test (x Int32) ENGINE = Memory", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "INSERT INTO test (x) VALUES", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "SELECT sum(x) FROM test WHERE x > 150", + "attributes": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "sentry.op": "db", + "sentry.origin": "auto.db.clickhouse_driver", + "server.address": "localhost", + "server.port": 9000, + }, + "trace_id": trace_id, + "parent_span_id": span_id, + }, + { + "name": "custom parent", + "attributes": [], + "trace_id": trace_id, + }, + ] + + for span in expected_spans: + span["attributes"] = ApproxDict(span["attributes"]) + + for span in spans: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("end_timestamp", None) + span.pop("is_segment", None) + span.pop("status", None) + + assert spans == expected_spans + else: + events = capture_events() + + transaction_trace_id = None + transaction_span_id = None + + with start_transaction(name="test_clickhouse_transaction") as transaction: + transaction_trace_id = transaction.trace_id + transaction_span_id = transaction.span_id + + conn = connect("clickhouse://localhost") + cursor = conn.cursor() + cursor.execute("DROP TABLE IF EXISTS test") + cursor.execute("CREATE TABLE test (x Int32) ENGINE = Memory") + cursor.executemany("INSERT INTO test (x) VALUES", [{"x": 100}]) + cursor.executemany("INSERT INTO test (x) VALUES", [[170], [200]]) + cursor.execute("SELECT sum(x) FROM test WHERE x > %(minv)i", {"minv": 150}) + res = cursor.fetchall() - expected_spans = [ - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "DROP TABLE IF EXISTS test", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.result": [[], []], + assert res[0][0] == 370 + + (event,) = events + + expected_spans = [ + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "DROP TABLE IF EXISTS test", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.result": [[], []], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "CREATE TABLE test (x Int32) ENGINE = Memory", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.result": [[], []], + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "CREATE TABLE test (x Int32) ENGINE = Memory", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.result": [[], []], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.params": [{"x": 100}], + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.params": [{"x": 100}], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "INSERT INTO test (x) VALUES", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.params": [[170], [200]], + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "INSERT INTO test (x) VALUES", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.params": [[170], [200]], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - { - "op": "db", - "origin": "auto.db.clickhouse_driver", - "description": "SELECT sum(x) FROM test WHERE x > 150", - "data": { - "db.system": "clickhouse", - "db.name": "", - "db.user": "default", - "server.address": "localhost", - "server.port": 9000, - "db.params": {"minv": 150}, - "db.result": [[[370]], [["sum(x)", "Int64"]]], + { + "op": "db", + "origin": "auto.db.clickhouse_driver", + "description": "SELECT sum(x) FROM test WHERE x > 150", + "data": { + "db.system": "clickhouse", + "db.name": "", + "db.user": "default", + "server.address": "localhost", + "server.port": 9000, + "db.params": {"minv": 150}, + "db.result": [[[370]], [["sum(x)", "Int64"]]], + }, + "same_process_as_parent": True, + "trace_id": transaction_trace_id, + "parent_span_id": transaction_span_id, }, - "same_process_as_parent": True, - "trace_id": transaction_trace_id, - "parent_span_id": transaction_span_id, - }, - ] + ] - if not EXPECT_PARAMS_IN_SELECT: - expected_spans[-1]["data"].pop("db.params", None) + if not EXPECT_PARAMS_IN_SELECT: + expected_spans[-1]["data"].pop("db.params", None) - for span in expected_spans: - span["data"] = ApproxDict(span["data"]) + for span in expected_spans: + span["data"] = ApproxDict(span["data"]) - for span in event["spans"]: - span.pop("span_id", None) - span.pop("start_timestamp", None) - span.pop("timestamp", None) + for span in event["spans"]: + span.pop("span_id", None) + span.pop("start_timestamp", None) + span.pop("timestamp", None) - assert event["spans"] == expected_spans + assert event["spans"] == expected_spans -def test_span_origin(sentry_init, capture_events, capture_envelopes) -> None: +@pytest.mark.parametrize("span_streaming", [True, False]) +def test_span_origin( + sentry_init, + capture_events, + capture_items, + capture_envelopes, + span_streaming, +): sentry_init( integrations=[ClickhouseDriverIntegration()], traces_sample_rate=1.0, + _experiments={"trace_lifecycle": "stream" if span_streaming else "static"}, ) + if span_streaming: + items = capture_items("span") - events = capture_events() + with sentry_sdk.traces.start_span(name="custom parent"): + conn = connect("clickhouse://localhost") + cursor = conn.cursor() + cursor.execute("SELECT 1") - with start_transaction(name="test_clickhouse_transaction"): - conn = connect("clickhouse://localhost") - cursor = conn.cursor() - cursor.execute("SELECT 1") + sentry_sdk.flush() + spans = [item.payload for item in items if item.type == "span"] - (event,) = events + assert spans[1]["attributes"]["sentry.origin"] == "manual" + assert spans[0]["attributes"]["sentry.origin"] == "auto.db.clickhouse_driver" + else: + events = capture_events() + + with start_transaction(name="test_clickhouse_transaction"): + conn = connect("clickhouse://localhost") + cursor = conn.cursor() + cursor.execute("SELECT 1") + + (event,) = events - assert event["contexts"]["trace"]["origin"] == "manual" - assert event["spans"][0]["origin"] == "auto.db.clickhouse_driver" + assert event["contexts"]["trace"]["origin"] == "manual" + assert event["spans"][0]["origin"] == "auto.db.clickhouse_driver" From b9fe91b0d7f059db4e87282318c9a19cdc21df97 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 5 Jun 2026 14:14:05 +0200 Subject: [PATCH 2/3] . --- sentry_sdk/integrations/clickhouse_driver.py | 6 +++--- .../clickhouse_driver/test_clickhouse_driver.py | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sentry_sdk/integrations/clickhouse_driver.py b/sentry_sdk/integrations/clickhouse_driver.py index 2acef16f42..61dc5dc018 100644 --- a/sentry_sdk/integrations/clickhouse_driver.py +++ b/sentry_sdk/integrations/clickhouse_driver.py @@ -84,7 +84,7 @@ def _inner(*args: "P.args", **kwargs: "P.kwargs") -> "T": if has_span_streaming_enabled(client.options): span = sentry_sdk.traces.start_span( - name=query, + name=query, # type: ignore attributes={ "sentry.op": OP.DB, "sentry.origin": ClickhouseDriverIntegration.origin, @@ -192,11 +192,11 @@ def wrapped_generator() -> "Iterator[Any]": def _set_db_data(span: "Union[Span, StreamedSpan]", connection: "Connection") -> None: if isinstance(span, StreamedSpan): - span.set_attribute(SPANDATA.DB_SYSTEM, "clickhouse") + span.set_attribute(SPANDATA.DB_SYSTEM_NAME, "clickhouse") span.set_attribute(SPANDATA.DB_DRIVER_NAME, "clickhouse-driver") span.set_attribute(SPANDATA.SERVER_ADDRESS, connection.host) span.set_attribute(SPANDATA.SERVER_PORT, connection.port) - span.set_attribute(SPANDATA.DB_NAME, connection.database) + span.set_attribute(SPANDATA.DB_NAMESPACE, connection.database) span.set_attribute(SPANDATA.DB_USER, connection.user) else: span.set_data(SPANDATA.DB_SYSTEM, "clickhouse") diff --git a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py index de8a5a1f00..e52e44cb05 100644 --- a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py +++ b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py @@ -267,7 +267,7 @@ def test_clickhouse_client_spans( assert res[0][0] == 370 sentry_sdk.flush() - spans = [item.payload for item in items if item.type == "span"] + spans = [item.payload for item in items] expected_spans = [ { @@ -554,7 +554,7 @@ def test_clickhouse_client_spans_with_pii( assert res[0][0] == 370 sentry_sdk.flush() - spans = [item.payload for item in items if item.type == "span"] + spans = [item.payload for item in items] expected_spans = [ { @@ -1002,7 +1002,7 @@ def test_clickhouse_dbapi_spans( res = cursor.fetchall() sentry_sdk.flush() - spans = [item.payload for item in items if item.type == "span"] + spans = [item.payload for item in items] expected_spans = [ { @@ -1257,7 +1257,7 @@ def test_clickhouse_dbapi_spans_with_pii( assert res[0][0] == 370 sentry_sdk.flush() - spans = [item.payload for item in items if item.type == "span"] + spans = [item.payload for item in items] expected_spans = [ { @@ -1491,7 +1491,7 @@ def test_span_origin( cursor.execute("SELECT 1") sentry_sdk.flush() - spans = [item.payload for item in items if item.type == "span"] + spans = [item.payload for item in items] assert spans[1]["attributes"]["sentry.origin"] == "manual" assert spans[0]["attributes"]["sentry.origin"] == "auto.db.clickhouse_driver" From 3dd6bc08f3545090f7d41050f5f041fdc23f4a56 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 5 Jun 2026 14:29:54 +0200 Subject: [PATCH 3/3] . --- sentry_sdk/integrations/clickhouse_driver.py | 17 ++-- .../test_clickhouse_driver.py | 80 +++++++++---------- 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/sentry_sdk/integrations/clickhouse_driver.py b/sentry_sdk/integrations/clickhouse_driver.py index 61dc5dc018..a7b9bf8f83 100644 --- a/sentry_sdk/integrations/clickhouse_driver.py +++ b/sentry_sdk/integrations/clickhouse_driver.py @@ -193,15 +193,16 @@ def wrapped_generator() -> "Iterator[Any]": def _set_db_data(span: "Union[Span, StreamedSpan]", connection: "Connection") -> None: if isinstance(span, StreamedSpan): span.set_attribute(SPANDATA.DB_SYSTEM_NAME, "clickhouse") - span.set_attribute(SPANDATA.DB_DRIVER_NAME, "clickhouse-driver") - span.set_attribute(SPANDATA.SERVER_ADDRESS, connection.host) - span.set_attribute(SPANDATA.SERVER_PORT, connection.port) span.set_attribute(SPANDATA.DB_NAMESPACE, connection.database) - span.set_attribute(SPANDATA.DB_USER, connection.user) + + set_on_span = span.set_attribute else: span.set_data(SPANDATA.DB_SYSTEM, "clickhouse") - span.set_data(SPANDATA.DB_DRIVER_NAME, "clickhouse-driver") - span.set_data(SPANDATA.SERVER_ADDRESS, connection.host) - span.set_data(SPANDATA.SERVER_PORT, connection.port) span.set_data(SPANDATA.DB_NAME, connection.database) - span.set_data(SPANDATA.DB_USER, connection.user) + + set_on_span = span.set_data + + set_on_span(SPANDATA.DB_DRIVER_NAME, "clickhouse-driver") + set_on_span(SPANDATA.SERVER_ADDRESS, connection.host) + set_on_span(SPANDATA.SERVER_PORT, connection.port) + set_on_span(SPANDATA.DB_USER, connection.user) diff --git a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py index e52e44cb05..33b62c7d89 100644 --- a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py +++ b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py @@ -273,9 +273,9 @@ def test_clickhouse_client_spans( { "name": "DROP TABLE IF EXISTS test", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -288,9 +288,9 @@ def test_clickhouse_client_spans( { "name": "CREATE TABLE test (x Int32) ENGINE = Memory", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -303,9 +303,9 @@ def test_clickhouse_client_spans( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -318,9 +318,9 @@ def test_clickhouse_client_spans( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -333,9 +333,9 @@ def test_clickhouse_client_spans( { "name": "SELECT sum(x) FROM test WHERE x > 150", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -560,8 +560,8 @@ def test_clickhouse_client_spans_with_pii( { "name": "DROP TABLE IF EXISTS test", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "server.address": "localhost", "server.port": 9000, @@ -574,8 +574,8 @@ def test_clickhouse_client_spans_with_pii( { "name": "CREATE TABLE test (x Int32) ENGINE = Memory", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "server.address": "localhost", "server.port": 9000, @@ -588,8 +588,8 @@ def test_clickhouse_client_spans_with_pii( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "server.address": "localhost", "server.port": 9000, @@ -602,8 +602,8 @@ def test_clickhouse_client_spans_with_pii( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "server.address": "localhost", "server.port": 9000, @@ -614,8 +614,8 @@ def test_clickhouse_client_spans_with_pii( { "name": "SELECT sum(x) FROM test WHERE x > 150", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "server.address": "localhost", "server.port": 9000, @@ -1008,9 +1008,9 @@ def test_clickhouse_dbapi_spans( { "name": "DROP TABLE IF EXISTS test", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1023,9 +1023,9 @@ def test_clickhouse_dbapi_spans( { "name": "CREATE TABLE test (x Int32) ENGINE = Memory", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1038,9 +1038,9 @@ def test_clickhouse_dbapi_spans( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1053,9 +1053,9 @@ def test_clickhouse_dbapi_spans( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1068,9 +1068,9 @@ def test_clickhouse_dbapi_spans( { "name": "SELECT sum(x) FROM test WHERE x > 150", "attributes": { - "db.system": "clickhouse", + "db.system.name": "clickhouse", "db.driver.name": "clickhouse-driver", - "db.name": "", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1263,8 +1263,8 @@ def test_clickhouse_dbapi_spans_with_pii( { "name": "DROP TABLE IF EXISTS test", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1277,8 +1277,8 @@ def test_clickhouse_dbapi_spans_with_pii( { "name": "CREATE TABLE test (x Int32) ENGINE = Memory", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1291,8 +1291,8 @@ def test_clickhouse_dbapi_spans_with_pii( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1305,8 +1305,8 @@ def test_clickhouse_dbapi_spans_with_pii( { "name": "INSERT INTO test (x) VALUES", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver", @@ -1319,8 +1319,8 @@ def test_clickhouse_dbapi_spans_with_pii( { "name": "SELECT sum(x) FROM test WHERE x > 150", "attributes": { - "db.system": "clickhouse", - "db.name": "", + "db.system.name": "clickhouse", + "db.namespace": "", "db.user": "default", "sentry.op": "db", "sentry.origin": "auto.db.clickhouse_driver",