Skip to content

Commit c5cfd87

Browse files
ericapisaniclaude
andcommitted
feat(redis): Set db.query.text and cache.key span attributes
When using span streaming, set SPANDATA.DB_QUERY_TEXT on db.redis spans and SPANDATA.CACHE_KEY on cache spans. These were already set as the span description/name but were missing from the attributes dict in the streaming path. Refs PY-2549 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c04b944 commit c5cfd87

5 files changed

Lines changed: 44 additions & 2 deletions

File tree

sentry_sdk/integrations/redis/_async_common.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import TYPE_CHECKING
22

33
import sentry_sdk
4-
from sentry_sdk.consts import OP
4+
from sentry_sdk.consts import OP, SPANDATA
55
from sentry_sdk.integrations.redis.consts import SPAN_ORIGIN
66
from sentry_sdk.integrations.redis.modules.caches import (
77
_compile_cache_span_properties,
@@ -117,6 +117,7 @@ async def _sentry_execute_command(
117117
attributes={
118118
"sentry.op": cache_properties["op"],
119119
"sentry.origin": SPAN_ORIGIN,
120+
SPANDATA.CACHE_KEY: cache_properties["description"],
120121
},
121122
)
122123
else:
@@ -136,6 +137,7 @@ async def _sentry_execute_command(
136137
attributes={
137138
"sentry.op": db_properties["op"],
138139
"sentry.origin": SPAN_ORIGIN,
140+
SPANDATA.DB_QUERY_TEXT: db_properties["description"],
139141
},
140142
)
141143
else:

sentry_sdk/integrations/redis/_sync_common.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import TYPE_CHECKING
22

33
import sentry_sdk
4-
from sentry_sdk.consts import OP
4+
from sentry_sdk.consts import OP, SPANDATA
55
from sentry_sdk.integrations.redis.consts import SPAN_ORIGIN
66
from sentry_sdk.integrations.redis.modules.caches import (
77
_compile_cache_span_properties,
@@ -116,6 +116,7 @@ def sentry_patched_execute_command(
116116
attributes={
117117
"sentry.op": cache_properties["op"],
118118
"sentry.origin": SPAN_ORIGIN,
119+
SPANDATA.CACHE_KEY: cache_properties["description"],
119120
},
120121
)
121122
else:
@@ -135,6 +136,7 @@ def sentry_patched_execute_command(
135136
attributes={
136137
"sentry.op": db_properties["op"],
137138
"sentry.origin": SPAN_ORIGIN,
139+
SPANDATA.DB_QUERY_TEXT: db_properties["description"],
138140
},
139141
)
140142
else:

tests/integrations/redis/test_redis.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ def test_sensitive_data(sentry_init, capture_events, capture_items, span_streami
139139

140140
assert parent_span["name"] == "custom parent"
141141
assert redis_span["name"] == "GET [Filtered]"
142+
assert redis_span["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET [Filtered]"
142143
assert redis_span["attributes"]["sentry.op"] == "db.redis"
143144
else:
144145
events = capture_events()
@@ -177,8 +178,10 @@ def test_pii_data_redacted(sentry_init, capture_events, capture_items, span_stre
177178

178179
assert parent["name"] == "custom parent"
179180
assert set1["name"] == "SET 'somekey1' [Filtered]"
181+
assert set1["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey1' [Filtered]"
180182
assert set1["attributes"]["sentry.op"] == "db.redis"
181183
assert set2["name"] == "SET 'somekey2' [Filtered]"
184+
assert set2["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey2' [Filtered]"
182185
assert get["name"] == "GET 'somekey2'"
183186
assert delete["name"] == "DEL 'somekey1' [Filtered]"
184187
else:
@@ -223,8 +226,16 @@ def test_pii_data_sent(sentry_init, capture_events, capture_items, span_streamin
223226

224227
assert parent["name"] == "custom parent"
225228
assert set1["name"] == "SET 'somekey1' 'my secret string1'"
229+
assert (
230+
set1["attributes"][SPANDATA.DB_QUERY_TEXT]
231+
== "SET 'somekey1' 'my secret string1'"
232+
)
226233
assert set1["attributes"]["sentry.op"] == "db.redis"
227234
assert set2["name"] == "SET 'somekey2' 'my secret string2'"
235+
assert (
236+
set2["attributes"][SPANDATA.DB_QUERY_TEXT]
237+
== "SET 'somekey2' 'my secret string2'"
238+
)
228239
assert get["name"] == "GET 'somekey2'"
229240
assert delete["name"] == "DEL 'somekey1' 'somekey2'"
230241
else:
@@ -271,8 +282,16 @@ def test_no_data_truncation_by_default(
271282

272283
assert parent["name"] == "custom parent"
273284
assert set1["name"] == f"SET 'somekey1' '{long_string}'"
285+
assert (
286+
set1["attributes"][SPANDATA.DB_QUERY_TEXT]
287+
== f"SET 'somekey1' '{long_string}'"
288+
)
274289
assert set1["attributes"]["sentry.op"] == "db.redis"
275290
assert set2["name"] == f"SET 'somekey2' '{short_string}'"
291+
assert (
292+
set2["attributes"][SPANDATA.DB_QUERY_TEXT]
293+
== f"SET 'somekey2' '{short_string}'"
294+
)
276295
else:
277296
events = capture_events()
278297
with start_transaction():
@@ -317,8 +336,10 @@ def test_data_truncation_custom(
317336

318337
assert parent["name"] == "custom parent"
319338
assert set1["name"] == expected_long
339+
assert set1["attributes"][SPANDATA.DB_QUERY_TEXT] == expected_long
320340
assert set1["attributes"]["sentry.op"] == "db.redis"
321341
assert set2["name"] == expected_short
342+
assert set2["attributes"][SPANDATA.DB_QUERY_TEXT] == expected_short
322343
else:
323344
events = capture_events()
324345
with start_transaction():
@@ -401,6 +422,7 @@ def test_db_connection_attributes_client(
401422
assert redis_span["name"] == "GET 'foobar'"
402423
attrs = redis_span["attributes"]
403424
assert attrs["sentry.op"] == "db.redis"
425+
assert attrs[SPANDATA.DB_QUERY_TEXT] == "GET 'foobar'"
404426
assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis"
405427
assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py"
406428
assert attrs[SPANDATA.DB_NAMESPACE] == "1"
@@ -508,6 +530,9 @@ def test_span_origin(sentry_init, capture_events, capture_items, span_streaming)
508530
assert parent_span["name"] == "custom parent"
509531
assert parent_span["attributes"]["sentry.origin"] == "manual"
510532
assert set_span["attributes"]["sentry.origin"] == "auto.db.redis"
533+
assert (
534+
set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey' [Filtered]"
535+
)
511536
assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis"
512537
else:
513538
events = capture_events()

tests/integrations/redis/test_redis_cache_module.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,28 @@ def test_cache_basic(sentry_init, capture_events, capture_items, span_streaming)
8383
assert payloads[1]["attributes"]["sentry.op"] == "db.redis"
8484
assert payloads[1]["attributes"][SPANDATA.DB_OPERATION_NAME] == "GET"
8585
assert payloads[2]["attributes"]["sentry.op"] == "cache.get"
86+
assert payloads[2]["attributes"][SPANDATA.CACHE_KEY] == ["mycachekey"]
8687

8788
# set: db then cache.put
8889
assert payloads[3]["attributes"]["sentry.op"] == "db.redis"
8990
assert payloads[3]["attributes"][SPANDATA.DB_OPERATION_NAME] == "SET"
9091
assert payloads[4]["attributes"]["sentry.op"] == "cache.put"
92+
assert payloads[4]["attributes"][SPANDATA.CACHE_KEY] == ["mycachekey1"]
9193

9294
# setex: db then cache.put
9395
assert payloads[5]["attributes"]["sentry.op"] == "db.redis"
9496
assert payloads[5]["attributes"][SPANDATA.DB_OPERATION_NAME] == "SETEX"
9597
assert payloads[6]["attributes"]["sentry.op"] == "cache.put"
98+
assert payloads[6]["attributes"][SPANDATA.CACHE_KEY] == ["mycachekey2"]
9699

97100
# mget: db then cache.get
98101
assert payloads[7]["attributes"]["sentry.op"] == "db.redis"
99102
assert payloads[7]["attributes"][SPANDATA.DB_OPERATION_NAME] == "MGET"
100103
assert payloads[8]["attributes"]["sentry.op"] == "cache.get"
104+
assert payloads[8]["attributes"][SPANDATA.CACHE_KEY] == [
105+
"mycachekey1",
106+
"mycachekey2",
107+
]
101108

102109
assert payloads[9]["name"] == "custom parent"
103110
else:
@@ -169,12 +176,14 @@ def test_cache_keys(sentry_init, capture_events, capture_items, span_streaming):
169176
assert payloads[1]["name"] == "GET 'blub'"
170177
assert payloads[2]["attributes"]["sentry.op"] == "cache.get"
171178
assert payloads[2]["name"] == "blub"
179+
assert payloads[2]["attributes"][SPANDATA.CACHE_KEY] == ["blub"]
172180

173181
# blubkeything: db then cache.get
174182
assert payloads[3]["attributes"]["sentry.op"] == "db.redis"
175183
assert payloads[3]["name"] == "GET 'blubkeything'"
176184
assert payloads[4]["attributes"]["sentry.op"] == "cache.get"
177185
assert payloads[4]["name"] == "blubkeything"
186+
assert payloads[4]["attributes"][SPANDATA.CACHE_KEY] == ["blubkeything"]
178187

179188
# bl: db only (no prefix match)
180189
assert payloads[5]["attributes"]["sentry.op"] == "db.redis"

tests/integrations/redis/test_redis_cache_module_async.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
)
1616

1717
import sentry_sdk
18+
from sentry_sdk.consts import SPANDATA
1819
from sentry_sdk.integrations.redis import RedisIntegration
1920
from sentry_sdk.utils import parse_version
2021

@@ -83,6 +84,7 @@ async def test_cache_basic(sentry_init, capture_events, capture_items, span_stre
8384
assert parent_span["name"] == "custom parent"
8485
assert db_span["attributes"]["sentry.op"] == "db.redis"
8586
assert cache_span["attributes"]["sentry.op"] == "cache.get"
87+
assert cache_span["attributes"][SPANDATA.CACHE_KEY] == ["myasynccachekey"]
8688
else:
8789
events = capture_events()
8890
with sentry_sdk.start_transaction():
@@ -132,12 +134,14 @@ async def test_cache_keys(sentry_init, capture_events, capture_items, span_strea
132134
assert payloads[1]["name"] == "GET 'ablub'"
133135
assert payloads[2]["attributes"]["sentry.op"] == "cache.get"
134136
assert payloads[2]["name"] == "ablub"
137+
assert payloads[2]["attributes"][SPANDATA.CACHE_KEY] == ["ablub"]
135138

136139
# ablubkeything: db then cache.get
137140
assert payloads[3]["attributes"]["sentry.op"] == "db.redis"
138141
assert payloads[3]["name"] == "GET 'ablubkeything'"
139142
assert payloads[4]["attributes"]["sentry.op"] == "cache.get"
140143
assert payloads[4]["name"] == "ablubkeything"
144+
assert payloads[4]["attributes"][SPANDATA.CACHE_KEY] == ["ablubkeything"]
141145

142146
# abl: db only (no prefix match)
143147
assert payloads[5]["attributes"]["sentry.op"] == "db.redis"

0 commit comments

Comments
 (0)