diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 73e5a6d9cb..25a50a12b2 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -441,6 +441,12 @@ class SPANDATA: Example: myDatabase """ + DB_DRIVER_NAME = "db.driver.name" + """ + The name of the database driver being used for the connection. + Example: "psycopg2" + """ + DB_OPERATION = "db.operation" """ The name of the operation being executed, e.g. the MongoDB command name such as findAndModify, or the SQL keyword. diff --git a/sentry_sdk/integrations/asyncpg.py b/sentry_sdk/integrations/asyncpg.py index d1cf6fcc92..29f3bad152 100644 --- a/sentry_sdk/integrations/asyncpg.py +++ b/sentry_sdk/integrations/asyncpg.py @@ -184,6 +184,7 @@ async def _inner(*args: "Any", **kwargs: "Any") -> "T": pass span.set_data(SPANDATA.DB_NAME, database) span.set_data(SPANDATA.DB_USER, user) + span.set_data(SPANDATA.DB_DRIVER_NAME, "asyncpg") with capture_internal_exceptions(): sentry_sdk.add_breadcrumb( @@ -198,6 +199,7 @@ async def _inner(*args: "Any", **kwargs: "Any") -> "T": def _set_db_data(span: "Span", conn: "Any") -> None: span.set_data(SPANDATA.DB_SYSTEM, "postgresql") + span.set_data(SPANDATA.DB_DRIVER_NAME, "asyncpg") addr = conn._addr if addr: diff --git a/sentry_sdk/integrations/clickhouse_driver.py b/sentry_sdk/integrations/clickhouse_driver.py index 7bbea94210..3b7ec9891e 100644 --- a/sentry_sdk/integrations/clickhouse_driver.py +++ b/sentry_sdk/integrations/clickhouse_driver.py @@ -165,6 +165,7 @@ def wrapped_generator() -> "Iterator[Any]": 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) diff --git a/sentry_sdk/integrations/pymongo.py b/sentry_sdk/integrations/pymongo.py index 86399b54d1..59daab34da 100644 --- a/sentry_sdk/integrations/pymongo.py +++ b/sentry_sdk/integrations/pymongo.py @@ -88,6 +88,7 @@ def _get_db_data(event: "Any") -> "Dict[str, Any]": data = {} data[SPANDATA.DB_SYSTEM] = "mongodb" + data[SPANDATA.DB_DRIVER_NAME] = "pymongo" db_name = event.database_name if db_name is not None: @@ -128,6 +129,7 @@ def started(self, event: "CommandStartedEvent") -> None: tags = { "db.name": event.database_name, SPANDATA.DB_SYSTEM: "mongodb", + SPANDATA.DB_DRIVER_NAME: "pymongo", SPANDATA.DB_OPERATION: event.command_name, SPANDATA.DB_MONGODB_COLLECTION: command.get(event.command_name), } diff --git a/sentry_sdk/integrations/redis/modules/queries.py b/sentry_sdk/integrations/redis/modules/queries.py index 3e8a820f44..c7780099c3 100644 --- a/sentry_sdk/integrations/redis/modules/queries.py +++ b/sentry_sdk/integrations/redis/modules/queries.py @@ -44,6 +44,7 @@ def _get_db_span_description( def _set_db_data_on_span(span: "Span", connection_params: "dict[str, Any]") -> None: span.set_data(SPANDATA.DB_SYSTEM, "redis") + span.set_data(SPANDATA.DB_DRIVER_NAME, "redis-py") db = connection_params.get("db") if db is not None: diff --git a/sentry_sdk/integrations/sqlalchemy.py b/sentry_sdk/integrations/sqlalchemy.py index 7d3ed95373..a4354f4228 100644 --- a/sentry_sdk/integrations/sqlalchemy.py +++ b/sentry_sdk/integrations/sqlalchemy.py @@ -137,6 +137,13 @@ def _set_db_data(span: "Span", conn: "Any") -> None: if db_system is not None: span.set_data(SPANDATA.DB_SYSTEM, db_system) + try: + driver = conn.dialect.driver + if driver: + span.set_data(SPANDATA.DB_DRIVER_NAME, driver) + except Exception: + pass + if conn.engine.url is None: return diff --git a/tests/integrations/asyncpg/test_asyncpg.py b/tests/integrations/asyncpg/test_asyncpg.py index e3e9907880..2dcce52070 100644 --- a/tests/integrations/asyncpg/test_asyncpg.py +++ b/tests/integrations/asyncpg/test_asyncpg.py @@ -49,6 +49,7 @@ def _get_db_name(): "db.name": PG_NAME, "db.system": "postgresql", "db.user": PG_USER, + "db.driver.name": "asyncpg", "server.address": PG_HOST, "server.port": PG_PORT, } diff --git a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py index 635f9334c4..b501aa3531 100644 --- a/tests/integrations/clickhouse_driver/test_clickhouse_driver.py +++ b/tests/integrations/clickhouse_driver/test_clickhouse_driver.py @@ -42,6 +42,7 @@ def test_clickhouse_client_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -54,6 +55,7 @@ def test_clickhouse_client_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -66,6 +68,7 @@ def test_clickhouse_client_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -78,6 +81,7 @@ def test_clickhouse_client_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -90,6 +94,7 @@ def test_clickhouse_client_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -257,6 +262,7 @@ def test_clickhouse_client_spans( "description": "DROP TABLE IF EXISTS test", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -272,6 +278,7 @@ def test_clickhouse_client_spans( "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", @@ -287,6 +294,7 @@ def test_clickhouse_client_spans( "description": "INSERT INTO test (x) VALUES", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -302,6 +310,7 @@ def test_clickhouse_client_spans( "description": "INSERT INTO test (x) VALUES", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -317,6 +326,7 @@ def test_clickhouse_client_spans( "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", @@ -529,6 +539,7 @@ def test_clickhouse_dbapi_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -541,6 +552,7 @@ def test_clickhouse_dbapi_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -553,6 +565,7 @@ def test_clickhouse_dbapi_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -565,6 +578,7 @@ def test_clickhouse_dbapi_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -577,6 +591,7 @@ def test_clickhouse_dbapi_breadcrumbs(sentry_init, capture_events) -> None: "category": "query", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -737,6 +752,7 @@ def test_clickhouse_dbapi_spans(sentry_init, capture_events, capture_envelopes) "description": "DROP TABLE IF EXISTS test", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -752,6 +768,7 @@ def test_clickhouse_dbapi_spans(sentry_init, capture_events, capture_envelopes) "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", @@ -767,6 +784,7 @@ def test_clickhouse_dbapi_spans(sentry_init, capture_events, capture_envelopes) "description": "INSERT INTO test (x) VALUES", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -782,6 +800,7 @@ def test_clickhouse_dbapi_spans(sentry_init, capture_events, capture_envelopes) "description": "INSERT INTO test (x) VALUES", "data": { "db.system": "clickhouse", + "db.driver.name": "clickhouse-driver", "db.name": "", "db.user": "default", "server.address": "localhost", @@ -797,6 +816,7 @@ def test_clickhouse_dbapi_spans(sentry_init, capture_events, capture_envelopes) "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", diff --git a/tests/integrations/pymongo/test_pymongo.py b/tests/integrations/pymongo/test_pymongo.py index 0669f73c30..b57061b0a0 100644 --- a/tests/integrations/pymongo/test_pymongo.py +++ b/tests/integrations/pymongo/test_pymongo.py @@ -52,11 +52,13 @@ def test_transactions(sentry_init, capture_events, mongo_server, with_pii): common_tags = { "db.name": "test_db", "db.system": "mongodb", + "db.driver.name": "pymongo", "net.peer.name": mongo_server.host, "net.peer.port": str(mongo_server.port), } for span in find, insert_success, insert_fail: assert span["data"][SPANDATA.DB_SYSTEM] == "mongodb" + assert span["data"][SPANDATA.DB_DRIVER_NAME] == "pymongo" assert span["data"][SPANDATA.DB_NAME] == "test_db" assert span["data"][SPANDATA.SERVER_ADDRESS] == "localhost" assert span["data"][SPANDATA.SERVER_PORT] == mongo_server.port @@ -136,6 +138,7 @@ def test_breadcrumbs(sentry_init, capture_events, mongo_server, with_pii): assert crumb["data"] == { "db.name": "test_db", "db.system": "mongodb", + "db.driver.name": "pymongo", "db.operation": "find", "net.peer.name": mongo_server.host, "net.peer.port": str(mongo_server.port), diff --git a/tests/integrations/redis/test_redis.py b/tests/integrations/redis/test_redis.py index 1861e7116f..84c5699d14 100644 --- a/tests/integrations/redis/test_redis.py +++ b/tests/integrations/redis/test_redis.py @@ -262,6 +262,7 @@ def test_db_connection_attributes_client(sentry_init, capture_events): assert span["op"] == "db.redis" assert span["description"] == "GET 'foobar'" assert span["data"][SPANDATA.DB_SYSTEM] == "redis" + assert span["data"][SPANDATA.DB_DRIVER_NAME] == "redis-py" assert span["data"][SPANDATA.DB_NAME] == "1" assert span["data"][SPANDATA.SERVER_ADDRESS] == "localhost" assert span["data"][SPANDATA.SERVER_PORT] == 63791 @@ -288,6 +289,7 @@ def test_db_connection_attributes_pipeline(sentry_init, capture_events): assert span["op"] == "db.redis" assert span["description"] == "redis.pipeline.execute" assert span["data"][SPANDATA.DB_SYSTEM] == "redis" + assert span["data"][SPANDATA.DB_DRIVER_NAME] == "redis-py" assert span["data"][SPANDATA.DB_NAME] == "1" assert span["data"][SPANDATA.SERVER_ADDRESS] == "localhost" assert span["data"][SPANDATA.SERVER_PORT] == 63791 diff --git a/tests/integrations/sqlalchemy/test_sqlalchemy.py b/tests/integrations/sqlalchemy/test_sqlalchemy.py index b6b42f9c39..7c7ce3d845 100644 --- a/tests/integrations/sqlalchemy/test_sqlalchemy.py +++ b/tests/integrations/sqlalchemy/test_sqlalchemy.py @@ -127,6 +127,7 @@ class Address(Base): for span in event["spans"]: assert span["data"][SPANDATA.DB_SYSTEM] == "sqlite" + assert span["data"][SPANDATA.DB_DRIVER_NAME] == "pysqlite" assert span["data"][SPANDATA.DB_NAME] == ":memory:" assert SPANDATA.SERVER_ADDRESS not in span["data"] assert SPANDATA.SERVER_PORT not in span["data"] @@ -201,6 +202,7 @@ class Address(Base): for span in event["spans"]: assert span["data"][SPANDATA.DB_SYSTEM] == "sqlite" + assert span["data"][SPANDATA.DB_DRIVER_NAME] == "pysqlite" assert SPANDATA.DB_NAME not in span["data"] assert SPANDATA.SERVER_ADDRESS not in span["data"] assert SPANDATA.SERVER_PORT not in span["data"]