Repository: getsentry/sentry-python

Issue:
Add `db.operation` to db spans
Should be added to:
- Redis (like `INCR`)
- SQL (Django ORM and SQLAlchemy) (like `SELECT`, `UPDATE`)
- MongoDB (like `findAndModify`)



Discussion:

Resolving patch:
diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py
--- a/sentry_sdk/consts.py
+++ b/sentry_sdk/consts.py
@@ -57,10 +57,17 @@ class SPANDATA:
     See: https://develop.sentry.dev/sdk/performance/span-data-conventions/
     """
 
+    DB_OPERATION = "db.operation"
+    """
+    The name of the operation being executed, e.g. the MongoDB command name such as findAndModify, or the SQL keyword.
+    See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md
+    Example: findAndModify, HMSET, SELECT
+    """
+
     DB_SYSTEM = "db.system"
     """
     An identifier for the database management system (DBMS) product being used.
-    See: https://github.com/open-telemetry/opentelemetry-specification/blob/24de67b3827a4e3ab2515cd8ab62d5bcf837c586/specification/trace/semantic_conventions/database.md
+    See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md
     Example: postgresql
     """
 
diff --git a/sentry_sdk/integrations/pymongo.py b/sentry_sdk/integrations/pymongo.py
--- a/sentry_sdk/integrations/pymongo.py
+++ b/sentry_sdk/integrations/pymongo.py
@@ -110,8 +110,8 @@ def started(self, event):
 
             tags = {
                 "db.name": event.database_name,
-                "db.system": "mongodb",
-                "db.operation": event.command_name,
+                SPANDATA.DB_SYSTEM: "mongodb",
+                SPANDATA.DB_OPERATION: event.command_name,
             }
 
             try:
diff --git a/sentry_sdk/integrations/redis.py b/sentry_sdk/integrations/redis.py
--- a/sentry_sdk/integrations/redis.py
+++ b/sentry_sdk/integrations/redis.py
@@ -196,6 +196,7 @@ def sentry_patched_execute_command(self, name, *args, **kwargs):
 
             if name:
                 span.set_tag("redis.command", name)
+                span.set_tag(SPANDATA.DB_OPERATION, name)
 
             if name and args:
                 name_low = name.lower()


Test patch:
diff --git a/tests/integrations/redis/test_redis.py b/tests/integrations/redis/test_redis.py
--- a/tests/integrations/redis/test_redis.py
+++ b/tests/integrations/redis/test_redis.py
@@ -27,6 +27,7 @@ def test_basic(sentry_init, capture_events):
             "redis.key": "foobar",
             "redis.command": "GET",
             "redis.is_cluster": False,
+            "db.operation": "GET",
         },
         "timestamp": crumb["timestamp"],
         "type": "redis",
@@ -207,6 +208,7 @@ def test_breadcrumbs(sentry_init, capture_events):
         "type": "redis",
         "category": "redis",
         "data": {
+            "db.operation": "SET",
             "redis.is_cluster": False,
             "redis.command": "SET",
             "redis.key": "somekey1",
@@ -218,6 +220,7 @@ def test_breadcrumbs(sentry_init, capture_events):
         "type": "redis",
         "category": "redis",
         "data": {
+            "db.operation": "SET",
             "redis.is_cluster": False,
             "redis.command": "SET",
             "redis.key": "somekey2",
diff --git a/tests/integrations/rediscluster/test_rediscluster.py b/tests/integrations/rediscluster/test_rediscluster.py
--- a/tests/integrations/rediscluster/test_rediscluster.py
+++ b/tests/integrations/rediscluster/test_rediscluster.py
@@ -43,6 +43,7 @@ def test_rediscluster_basic(rediscluster_cls, sentry_init, capture_events):
         "category": "redis",
         "message": "GET 'foobar'",
         "data": {
+            "db.operation": "GET",
             "redis.key": "foobar",
             "redis.command": "GET",
             "redis.is_cluster": True,