Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 949ff5b

Browse filesBrowse files
authored
Fix breadcrumbs in redis (#3680)
This moves the creation of `redis` breadcrumbs from the `maybe_create_breadcrumbs_from_span` into the integrations. And as well fixes some span related tests by using `render_span_tree`.
1 parent e72e62f commit 949ff5b
Copy full SHA for 949ff5b

File tree

Expand file treeCollapse file tree

13 files changed

+292
-210
lines changed
Filter options
Expand file treeCollapse file tree

13 files changed

+292
-210
lines changed

‎sentry_sdk/integrations/redis/_async_common.py

Copy file name to clipboardExpand all lines: sentry_sdk/integrations/redis/_async_common.py
+27-17Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
from sentry_sdk.integrations.redis.consts import SPAN_ORIGIN
44
from sentry_sdk.integrations.redis.modules.caches import (
55
_compile_cache_span_properties,
6-
_set_cache_data,
6+
_get_cache_data,
77
)
88
from sentry_sdk.integrations.redis.modules.queries import _compile_db_span_properties
99
from sentry_sdk.integrations.redis.utils import (
10-
_set_client_data,
11-
_set_pipeline_data,
10+
_create_breadcrumb,
11+
_get_client_data,
12+
_get_pipeline_data,
13+
_update_span,
1214
)
1315
from sentry_sdk.tracing import Span
1416
from sentry_sdk.utils import capture_internal_exceptions
@@ -23,9 +25,9 @@
2325

2426

2527
def patch_redis_async_pipeline(
26-
pipeline_cls, is_cluster, get_command_args_fn, set_db_data_fn
28+
pipeline_cls, is_cluster, get_command_args_fn, get_db_data_fn
2729
):
28-
# type: (Union[type[Pipeline[Any]], type[ClusterPipeline[Any]]], bool, Any, Callable[[Span, Any], None]) -> None
30+
# type: (Union[type[Pipeline[Any]], type[ClusterPipeline[Any]]], bool, Any, Callable[[Any], dict[str, Any]]) -> None
2931
old_execute = pipeline_cls.execute
3032

3133
from sentry_sdk.integrations.redis import RedisIntegration
@@ -41,22 +43,25 @@ async def _sentry_execute(self, *args, **kwargs):
4143
origin=SPAN_ORIGIN,
4244
) as span:
4345
with capture_internal_exceptions():
44-
set_db_data_fn(span, self)
45-
_set_pipeline_data(
46-
span,
47-
is_cluster,
48-
get_command_args_fn,
49-
False if is_cluster else self.is_transaction,
50-
self._command_stack if is_cluster else self.command_stack,
46+
span_data = get_db_data_fn(self)
47+
pipeline_data = _get_pipeline_data(
48+
is_cluster=is_cluster,
49+
get_command_args_fn=get_command_args_fn,
50+
is_transaction=False if is_cluster else self.is_transaction,
51+
command_stack=(
52+
self._command_stack if is_cluster else self.command_stack
53+
),
5154
)
55+
_update_span(span, span_data, pipeline_data)
56+
_create_breadcrumb("redis.pipeline.execute", span_data, pipeline_data)
5257

5358
return await old_execute(self, *args, **kwargs)
5459

5560
pipeline_cls.execute = _sentry_execute # type: ignore
5661

5762

58-
def patch_redis_async_client(cls, is_cluster, set_db_data_fn):
59-
# type: (Union[type[StrictRedis[Any]], type[RedisCluster[Any]]], bool, Callable[[Span, Any], None]) -> None
63+
def patch_redis_async_client(cls, is_cluster, get_db_data_fn):
64+
# type: (Union[type[StrictRedis[Any]], type[RedisCluster[Any]]], bool, Callable[[Any], dict[str, Any]]) -> None
6065
old_execute_command = cls.execute_command
6166

6267
from sentry_sdk.integrations.redis import RedisIntegration
@@ -92,15 +97,20 @@ async def _sentry_execute_command(self, name, *args, **kwargs):
9297
)
9398
db_span.__enter__()
9499

95-
set_db_data_fn(db_span, self)
96-
_set_client_data(db_span, is_cluster, name, *args)
100+
db_span_data = get_db_data_fn(self)
101+
db_client_span_data = _get_client_data(is_cluster, name, *args)
102+
_update_span(db_span, db_span_data, db_client_span_data)
103+
_create_breadcrumb(
104+
db_properties["description"], db_span_data, db_client_span_data
105+
)
97106

98107
value = await old_execute_command(self, name, *args, **kwargs)
99108

100109
db_span.__exit__(None, None, None)
101110

102111
if cache_span:
103-
_set_cache_data(cache_span, self, cache_properties, value)
112+
cache_span_data = _get_cache_data(self, cache_properties, value)
113+
_update_span(cache_span, cache_span_data)
104114
cache_span.__exit__(None, None, None)
105115

106116
return value

‎sentry_sdk/integrations/redis/_sync_common.py

Copy file name to clipboardExpand all lines: sentry_sdk/integrations/redis/_sync_common.py
+25-17Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
from sentry_sdk.integrations.redis.consts import SPAN_ORIGIN
44
from sentry_sdk.integrations.redis.modules.caches import (
55
_compile_cache_span_properties,
6-
_set_cache_data,
6+
_get_cache_data,
77
)
88
from sentry_sdk.integrations.redis.modules.queries import _compile_db_span_properties
99
from sentry_sdk.integrations.redis.utils import (
10-
_set_client_data,
11-
_set_pipeline_data,
10+
_create_breadcrumb,
11+
_get_client_data,
12+
_get_pipeline_data,
13+
_update_span,
1214
)
1315
from sentry_sdk.tracing import Span
1416
from sentry_sdk.utils import capture_internal_exceptions
@@ -24,9 +26,9 @@ def patch_redis_pipeline(
2426
pipeline_cls,
2527
is_cluster,
2628
get_command_args_fn,
27-
set_db_data_fn,
29+
get_db_data_fn,
2830
):
29-
# type: (Any, bool, Any, Callable[[Span, Any], None]) -> None
31+
# type: (Any, bool, Any, Callable[[Any], dict[str, Any]]) -> None
3032
old_execute = pipeline_cls.execute
3133

3234
from sentry_sdk.integrations.redis import RedisIntegration
@@ -42,22 +44,23 @@ def sentry_patched_execute(self, *args, **kwargs):
4244
origin=SPAN_ORIGIN,
4345
) as span:
4446
with capture_internal_exceptions():
45-
set_db_data_fn(span, self)
46-
_set_pipeline_data(
47-
span,
48-
is_cluster,
49-
get_command_args_fn,
50-
False if is_cluster else self.transaction,
51-
self.command_stack,
47+
span_data = get_db_data_fn(self)
48+
pipeline_data = _get_pipeline_data(
49+
is_cluster=is_cluster,
50+
get_command_args_fn=get_command_args_fn,
51+
is_transaction=False if is_cluster else self.transaction,
52+
command_stack=self.command_stack,
5253
)
54+
_update_span(span, span_data, pipeline_data)
55+
_create_breadcrumb("redis.pipeline.execute", span_data, pipeline_data)
5356

5457
return old_execute(self, *args, **kwargs)
5558

5659
pipeline_cls.execute = sentry_patched_execute
5760

5861

59-
def patch_redis_client(cls, is_cluster, set_db_data_fn):
60-
# type: (Any, bool, Callable[[Span, Any], None]) -> None
62+
def patch_redis_client(cls, is_cluster, get_db_data_fn):
63+
# type: (Any, bool, Callable[[Any], dict[str, Any]]) -> None
6164
"""
6265
This function can be used to instrument custom redis client classes or
6366
subclasses.
@@ -97,15 +100,20 @@ def sentry_patched_execute_command(self, name, *args, **kwargs):
97100
)
98101
db_span.__enter__()
99102

100-
set_db_data_fn(db_span, self)
101-
_set_client_data(db_span, is_cluster, name, *args)
103+
db_span_data = get_db_data_fn(self)
104+
db_client_span_data = _get_client_data(is_cluster, name, *args)
105+
_update_span(db_span, db_span_data, db_client_span_data)
106+
_create_breadcrumb(
107+
db_properties["description"], db_span_data, db_client_span_data
108+
)
102109

103110
value = old_execute_command(self, name, *args, **kwargs)
104111

105112
db_span.__exit__(None, None, None)
106113

107114
if cache_span:
108-
_set_cache_data(cache_span, self, cache_properties, value)
115+
cache_span_data = _get_cache_data(self, cache_properties, value)
116+
_update_span(cache_span, cache_span_data)
109117
cache_span.__exit__(None, None, None)
110118

111119
return value

‎sentry_sdk/integrations/redis/modules/caches.py

Copy file name to clipboardExpand all lines: sentry_sdk/integrations/redis/modules/caches.py
+13-9Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,24 @@ def _get_cache_span_description(redis_command, args, kwargs, integration):
7575
return description
7676

7777

78-
def _set_cache_data(span, redis_client, properties, return_value):
79-
# type: (Span, Any, dict[str, Any], Optional[Any]) -> None
78+
def _get_cache_data(redis_client, properties, return_value):
79+
# type: (Any, dict[str, Any], Optional[Any]) -> dict[str, Any]
80+
data = {}
81+
8082
with capture_internal_exceptions():
81-
span.set_data(SPANDATA.CACHE_KEY, properties["key"])
83+
data[SPANDATA.CACHE_KEY] = properties["key"]
8284

8385
if properties["redis_command"] in GET_COMMANDS:
8486
if return_value is not None:
85-
span.set_data(SPANDATA.CACHE_HIT, True)
87+
data[SPANDATA.CACHE_HIT] = True
8688
size = (
8789
len(str(return_value).encode("utf-8"))
8890
if not isinstance(return_value, bytes)
8991
else len(return_value)
9092
)
91-
span.set_data(SPANDATA.CACHE_ITEM_SIZE, size)
93+
data[SPANDATA.CACHE_ITEM_SIZE] = size
9294
else:
93-
span.set_data(SPANDATA.CACHE_HIT, False)
95+
data[SPANDATA.CACHE_HIT] = False
9496

9597
elif properties["redis_command"] in SET_COMMANDS:
9698
if properties["value"] is not None:
@@ -99,7 +101,7 @@ def _set_cache_data(span, redis_client, properties, return_value):
99101
if not isinstance(properties["value"], bytes)
100102
else len(properties["value"])
101103
)
102-
span.set_data(SPANDATA.CACHE_ITEM_SIZE, size)
104+
data[SPANDATA.CACHE_ITEM_SIZE] = size
103105

104106
try:
105107
connection_params = redis_client.connection_pool.connection_kwargs
@@ -114,8 +116,10 @@ def _set_cache_data(span, redis_client, properties, return_value):
114116

115117
host = connection_params.get("host")
116118
if host is not None:
117-
span.set_data(SPANDATA.NETWORK_PEER_ADDRESS, host)
119+
data[SPANDATA.NETWORK_PEER_ADDRESS] = host
118120

119121
port = connection_params.get("port")
120122
if port is not None:
121-
span.set_data(SPANDATA.NETWORK_PEER_PORT, port)
123+
data[SPANDATA.NETWORK_PEER_PORT] = port
124+
125+
return data

‎sentry_sdk/integrations/redis/modules/queries.py

Copy file name to clipboardExpand all lines: sentry_sdk/integrations/redis/modules/queries.py
+14-10Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,30 @@ def _get_db_span_description(integration, command_name, args):
4343
return description
4444

4545

46-
def _set_db_data_on_span(span, connection_params):
47-
# type: (Span, dict[str, Any]) -> None
48-
span.set_data(SPANDATA.DB_SYSTEM, "redis")
46+
def _get_connection_data(connection_params):
47+
# type: (dict[str, Any]) -> dict[str, Any]
48+
data = {
49+
SPANDATA.DB_SYSTEM: "redis",
50+
}
4951

5052
db = connection_params.get("db")
5153
if db is not None:
52-
span.set_data(SPANDATA.DB_NAME, str(db))
54+
data[SPANDATA.DB_NAME] = str(db)
5355

5456
host = connection_params.get("host")
5557
if host is not None:
56-
span.set_data(SPANDATA.SERVER_ADDRESS, host)
58+
data[SPANDATA.SERVER_ADDRESS] = host
5759

5860
port = connection_params.get("port")
5961
if port is not None:
60-
span.set_data(SPANDATA.SERVER_PORT, port)
62+
data[SPANDATA.SERVER_PORT] = port
63+
64+
return data
6165

6266

63-
def _set_db_data(span, redis_instance):
64-
# type: (Span, Redis[Any]) -> None
67+
def _get_db_data(redis_instance):
68+
# type: (Redis[Any]) -> dict[str, Any]
6569
try:
66-
_set_db_data_on_span(span, redis_instance.connection_pool.connection_kwargs)
70+
return _get_connection_data(redis_instance.connection_pool.connection_kwargs)
6771
except AttributeError:
68-
pass # connections_kwargs may be missing in some cases
72+
return {} # connections_kwargs may be missing in some cases

‎sentry_sdk/integrations/redis/rb.py

Copy file name to clipboardExpand all lines: sentry_sdk/integrations/redis/rb.py
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
from sentry_sdk.integrations.redis._sync_common import patch_redis_client
8-
from sentry_sdk.integrations.redis.modules.queries import _set_db_data
8+
from sentry_sdk.integrations.redis.modules.queries import _get_db_data
99

1010

1111
def _patch_rb():
@@ -18,15 +18,15 @@ def _patch_rb():
1818
patch_redis_client(
1919
rb.clients.FanoutClient,
2020
is_cluster=False,
21-
set_db_data_fn=_set_db_data,
21+
get_db_data_fn=_get_db_data,
2222
)
2323
patch_redis_client(
2424
rb.clients.MappingClient,
2525
is_cluster=False,
26-
set_db_data_fn=_set_db_data,
26+
get_db_data_fn=_get_db_data,
2727
)
2828
patch_redis_client(
2929
rb.clients.RoutingClient,
3030
is_cluster=False,
31-
set_db_data_fn=_set_db_data,
31+
get_db_data_fn=_get_db_data,
3232
)

‎sentry_sdk/integrations/redis/redis.py

Copy file name to clipboardExpand all lines: sentry_sdk/integrations/redis/redis.py
+6-6Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
patch_redis_client,
99
patch_redis_pipeline,
1010
)
11-
from sentry_sdk.integrations.redis.modules.queries import _set_db_data
11+
from sentry_sdk.integrations.redis.modules.queries import _get_db_data
1212

1313
from typing import TYPE_CHECKING
1414

@@ -26,13 +26,13 @@ def _patch_redis(StrictRedis, client): # noqa: N803
2626
patch_redis_client(
2727
StrictRedis,
2828
is_cluster=False,
29-
set_db_data_fn=_set_db_data,
29+
get_db_data_fn=_get_db_data,
3030
)
3131
patch_redis_pipeline(
3232
client.Pipeline,
3333
is_cluster=False,
3434
get_command_args_fn=_get_redis_command_args,
35-
set_db_data_fn=_set_db_data,
35+
get_db_data_fn=_get_db_data,
3636
)
3737
try:
3838
strict_pipeline = client.StrictPipeline
@@ -43,7 +43,7 @@ def _patch_redis(StrictRedis, client): # noqa: N803
4343
strict_pipeline,
4444
is_cluster=False,
4545
get_command_args_fn=_get_redis_command_args,
46-
set_db_data_fn=_set_db_data,
46+
get_db_data_fn=_get_db_data,
4747
)
4848

4949
try:
@@ -59,11 +59,11 @@ def _patch_redis(StrictRedis, client): # noqa: N803
5959
patch_redis_async_client(
6060
redis.asyncio.client.StrictRedis,
6161
is_cluster=False,
62-
set_db_data_fn=_set_db_data,
62+
get_db_data_fn=_get_db_data,
6363
)
6464
patch_redis_async_pipeline(
6565
redis.asyncio.client.Pipeline,
6666
False,
6767
_get_redis_command_args,
68-
set_db_data_fn=_set_db_data,
68+
get_db_data_fn=_get_db_data,
6969
)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.