sentry-sdk 3.0.0a2__py2.py3-none-any.whl → 3.0.0a4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sentry-sdk might be problematic. Click here for more details.
- sentry_sdk/__init__.py +4 -0
- sentry_sdk/_compat.py +5 -12
- sentry_sdk/_init_implementation.py +7 -7
- sentry_sdk/_log_batcher.py +17 -29
- sentry_sdk/_lru_cache.py +7 -9
- sentry_sdk/_queue.py +2 -4
- sentry_sdk/_types.py +9 -16
- sentry_sdk/_werkzeug.py +5 -7
- sentry_sdk/ai/monitoring.py +45 -33
- sentry_sdk/ai/utils.py +8 -5
- sentry_sdk/api.py +91 -87
- sentry_sdk/attachments.py +10 -12
- sentry_sdk/client.py +119 -159
- sentry_sdk/consts.py +432 -223
- sentry_sdk/crons/api.py +16 -17
- sentry_sdk/crons/decorator.py +25 -27
- sentry_sdk/debug.py +4 -6
- sentry_sdk/envelope.py +46 -112
- sentry_sdk/feature_flags.py +9 -15
- sentry_sdk/integrations/__init__.py +24 -19
- sentry_sdk/integrations/_asgi_common.py +16 -18
- sentry_sdk/integrations/_wsgi_common.py +22 -33
- sentry_sdk/integrations/aiohttp.py +33 -31
- sentry_sdk/integrations/anthropic.py +43 -38
- sentry_sdk/integrations/argv.py +3 -4
- sentry_sdk/integrations/ariadne.py +16 -18
- sentry_sdk/integrations/arq.py +20 -29
- sentry_sdk/integrations/asgi.py +63 -37
- sentry_sdk/integrations/asyncio.py +15 -17
- sentry_sdk/integrations/asyncpg.py +1 -1
- sentry_sdk/integrations/atexit.py +6 -10
- sentry_sdk/integrations/aws_lambda.py +26 -36
- sentry_sdk/integrations/beam.py +10 -18
- sentry_sdk/integrations/boto3.py +20 -18
- sentry_sdk/integrations/bottle.py +25 -34
- sentry_sdk/integrations/celery/__init__.py +40 -59
- sentry_sdk/integrations/celery/beat.py +22 -26
- sentry_sdk/integrations/celery/utils.py +15 -17
- sentry_sdk/integrations/chalice.py +8 -10
- sentry_sdk/integrations/clickhouse_driver.py +22 -32
- sentry_sdk/integrations/cloud_resource_context.py +9 -16
- sentry_sdk/integrations/cohere.py +19 -25
- sentry_sdk/integrations/dedupe.py +5 -8
- sentry_sdk/integrations/django/__init__.py +69 -74
- sentry_sdk/integrations/django/asgi.py +25 -33
- sentry_sdk/integrations/django/caching.py +24 -20
- sentry_sdk/integrations/django/middleware.py +18 -21
- sentry_sdk/integrations/django/signals_handlers.py +12 -11
- sentry_sdk/integrations/django/templates.py +21 -18
- sentry_sdk/integrations/django/transactions.py +16 -11
- sentry_sdk/integrations/django/views.py +8 -12
- sentry_sdk/integrations/dramatiq.py +21 -21
- sentry_sdk/integrations/excepthook.py +10 -10
- sentry_sdk/integrations/executing.py +3 -4
- sentry_sdk/integrations/falcon.py +27 -42
- sentry_sdk/integrations/fastapi.py +13 -16
- sentry_sdk/integrations/flask.py +31 -38
- sentry_sdk/integrations/gcp.py +13 -16
- sentry_sdk/integrations/gnu_backtrace.py +7 -20
- sentry_sdk/integrations/gql.py +16 -17
- sentry_sdk/integrations/graphene.py +14 -13
- sentry_sdk/integrations/grpc/__init__.py +3 -2
- sentry_sdk/integrations/grpc/aio/client.py +2 -2
- sentry_sdk/integrations/grpc/aio/server.py +15 -14
- sentry_sdk/integrations/grpc/client.py +21 -11
- sentry_sdk/integrations/grpc/consts.py +2 -0
- sentry_sdk/integrations/grpc/server.py +12 -8
- sentry_sdk/integrations/httpx.py +11 -14
- sentry_sdk/integrations/huey.py +14 -21
- sentry_sdk/integrations/huggingface_hub.py +17 -17
- sentry_sdk/integrations/langchain.py +204 -114
- sentry_sdk/integrations/launchdarkly.py +13 -10
- sentry_sdk/integrations/litestar.py +40 -38
- sentry_sdk/integrations/logging.py +29 -36
- sentry_sdk/integrations/loguru.py +16 -20
- sentry_sdk/integrations/modules.py +3 -4
- sentry_sdk/integrations/openai.py +421 -204
- sentry_sdk/integrations/openai_agents/__init__.py +49 -0
- sentry_sdk/integrations/openai_agents/consts.py +1 -0
- sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
- sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
- sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
- sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
- sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
- sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
- sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
- sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
- sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
- sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
- sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
- sentry_sdk/integrations/openai_agents/utils.py +153 -0
- sentry_sdk/integrations/openfeature.py +12 -8
- sentry_sdk/integrations/pure_eval.py +6 -10
- sentry_sdk/integrations/pymongo.py +14 -18
- sentry_sdk/integrations/pyramid.py +31 -36
- sentry_sdk/integrations/quart.py +23 -28
- sentry_sdk/integrations/ray.py +73 -64
- sentry_sdk/integrations/redis/__init__.py +7 -4
- sentry_sdk/integrations/redis/_async_common.py +18 -12
- sentry_sdk/integrations/redis/_sync_common.py +16 -15
- sentry_sdk/integrations/redis/modules/caches.py +17 -8
- sentry_sdk/integrations/redis/modules/queries.py +9 -8
- sentry_sdk/integrations/redis/rb.py +3 -2
- sentry_sdk/integrations/redis/redis.py +4 -4
- sentry_sdk/integrations/redis/redis_cluster.py +10 -8
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
- sentry_sdk/integrations/redis/utils.py +21 -22
- sentry_sdk/integrations/rq.py +13 -16
- sentry_sdk/integrations/rust_tracing.py +10 -7
- sentry_sdk/integrations/sanic.py +34 -46
- sentry_sdk/integrations/serverless.py +22 -27
- sentry_sdk/integrations/socket.py +29 -17
- sentry_sdk/integrations/spark/__init__.py +1 -0
- sentry_sdk/integrations/spark/spark_driver.py +45 -83
- sentry_sdk/integrations/spark/spark_worker.py +7 -11
- sentry_sdk/integrations/sqlalchemy.py +22 -19
- sentry_sdk/integrations/starlette.py +89 -93
- sentry_sdk/integrations/starlite.py +31 -37
- sentry_sdk/integrations/statsig.py +5 -4
- sentry_sdk/integrations/stdlib.py +32 -28
- sentry_sdk/integrations/strawberry.py +63 -50
- sentry_sdk/integrations/sys_exit.py +7 -11
- sentry_sdk/integrations/threading.py +13 -15
- sentry_sdk/integrations/tornado.py +28 -32
- sentry_sdk/integrations/trytond.py +4 -3
- sentry_sdk/integrations/typer.py +8 -6
- sentry_sdk/integrations/unleash.py +5 -4
- sentry_sdk/integrations/wsgi.py +47 -46
- sentry_sdk/logger.py +13 -9
- sentry_sdk/monitor.py +16 -28
- sentry_sdk/opentelemetry/consts.py +11 -4
- sentry_sdk/opentelemetry/contextvars_context.py +17 -15
- sentry_sdk/opentelemetry/propagator.py +38 -21
- sentry_sdk/opentelemetry/sampler.py +51 -34
- sentry_sdk/opentelemetry/scope.py +46 -37
- sentry_sdk/opentelemetry/span_processor.py +43 -59
- sentry_sdk/opentelemetry/tracing.py +32 -12
- sentry_sdk/opentelemetry/utils.py +180 -196
- sentry_sdk/profiler/continuous_profiler.py +108 -97
- sentry_sdk/profiler/transaction_profiler.py +70 -97
- sentry_sdk/profiler/utils.py +11 -15
- sentry_sdk/scope.py +251 -264
- sentry_sdk/scrubber.py +22 -26
- sentry_sdk/serializer.py +48 -65
- sentry_sdk/session.py +44 -61
- sentry_sdk/sessions.py +35 -49
- sentry_sdk/spotlight.py +15 -21
- sentry_sdk/tracing.py +118 -184
- sentry_sdk/tracing_utils.py +103 -123
- sentry_sdk/transport.py +131 -157
- sentry_sdk/utils.py +278 -309
- sentry_sdk/worker.py +16 -28
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/METADATA +1 -1
- sentry_sdk-3.0.0a4.dist-info/RECORD +168 -0
- sentry_sdk-3.0.0a2.dist-info/RECORD +0 -154
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/WHEEL +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/top_level.txt +0 -0
sentry_sdk/integrations/ray.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import inspect
|
|
2
3
|
import sys
|
|
3
4
|
|
|
@@ -29,8 +30,7 @@ if TYPE_CHECKING:
|
|
|
29
30
|
DEFAULT_TRANSACTION_NAME = "unknown Ray function"
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
def _check_sentry_initialized():
|
|
33
|
-
# type: () -> None
|
|
33
|
+
def _check_sentry_initialized() -> None:
|
|
34
34
|
if sentry_sdk.get_client().is_active():
|
|
35
35
|
return
|
|
36
36
|
|
|
@@ -39,88 +39,98 @@ def _check_sentry_initialized():
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def _patch_ray_remote():
|
|
43
|
-
# type: () -> None
|
|
42
|
+
def _patch_ray_remote() -> None:
|
|
44
43
|
old_remote = ray.remote
|
|
45
44
|
|
|
46
45
|
@functools.wraps(old_remote)
|
|
47
|
-
def new_remote(
|
|
48
|
-
|
|
46
|
+
def new_remote(
|
|
47
|
+
f: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any
|
|
48
|
+
) -> Callable[..., Any]:
|
|
49
|
+
|
|
49
50
|
if inspect.isclass(f):
|
|
50
51
|
# Ray Actors
|
|
51
52
|
# (https://docs.ray.io/en/latest/ray-core/actors.html)
|
|
52
53
|
# are not supported
|
|
53
54
|
# (Only Ray Tasks are supported)
|
|
54
|
-
return old_remote(f, *args,
|
|
55
|
-
|
|
56
|
-
def
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
return old_remote(f, *args, **kwargs)
|
|
56
|
+
|
|
57
|
+
def wrapper(user_f: Callable[..., Any]) -> Any:
|
|
58
|
+
def new_func(
|
|
59
|
+
*f_args: Any, _tracing: Optional[dict[str, Any]] = None, **f_kwargs: Any
|
|
60
|
+
) -> Any:
|
|
61
|
+
_check_sentry_initialized()
|
|
62
|
+
|
|
63
|
+
root_span_name = (
|
|
64
|
+
qualname_from_function(user_f) or DEFAULT_TRANSACTION_NAME
|
|
65
|
+
)
|
|
66
|
+
sentry_sdk.get_current_scope().set_transaction_name(
|
|
67
|
+
root_span_name,
|
|
68
|
+
source=TransactionSource.TASK,
|
|
69
|
+
)
|
|
70
|
+
with sentry_sdk.continue_trace(_tracing or {}):
|
|
71
|
+
with sentry_sdk.start_span(
|
|
72
|
+
op=OP.QUEUE_TASK_RAY,
|
|
73
|
+
name=qualname_from_function(user_f),
|
|
74
|
+
origin=RayIntegration.origin,
|
|
75
|
+
source=TransactionSource.TASK,
|
|
76
|
+
) as root_span:
|
|
77
|
+
try:
|
|
78
|
+
result = user_f(*f_args, **f_kwargs)
|
|
79
|
+
root_span.set_status(SPANSTATUS.OK)
|
|
80
|
+
except Exception:
|
|
81
|
+
root_span.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
82
|
+
exc_info = sys.exc_info()
|
|
83
|
+
_capture_exception(exc_info)
|
|
84
|
+
reraise(*exc_info)
|
|
85
|
+
|
|
86
|
+
return result
|
|
87
|
+
|
|
88
|
+
if f:
|
|
89
|
+
rv = old_remote(new_func)
|
|
90
|
+
else:
|
|
91
|
+
rv = old_remote(*args, **kwargs)(new_func)
|
|
92
|
+
old_remote_method = rv.remote
|
|
93
|
+
|
|
94
|
+
def _remote_method_with_header_propagation(
|
|
95
|
+
*args: Any, **kwargs: Any
|
|
96
|
+
) -> Any:
|
|
97
|
+
"""
|
|
98
|
+
Ray Client
|
|
99
|
+
"""
|
|
69
100
|
with sentry_sdk.start_span(
|
|
70
|
-
op=OP.
|
|
71
|
-
name=
|
|
101
|
+
op=OP.QUEUE_SUBMIT_RAY,
|
|
102
|
+
name=qualname_from_function(user_f),
|
|
72
103
|
origin=RayIntegration.origin,
|
|
73
|
-
|
|
74
|
-
) as
|
|
104
|
+
only_as_child_span=True,
|
|
105
|
+
) as span:
|
|
106
|
+
tracing = {
|
|
107
|
+
k: v
|
|
108
|
+
for k, v in sentry_sdk.get_current_scope().iter_trace_propagation_headers()
|
|
109
|
+
}
|
|
75
110
|
try:
|
|
76
|
-
result =
|
|
77
|
-
|
|
111
|
+
result = old_remote_method(*args, **kwargs, _tracing=tracing)
|
|
112
|
+
span.set_status(SPANSTATUS.OK)
|
|
78
113
|
except Exception:
|
|
79
|
-
|
|
114
|
+
span.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
80
115
|
exc_info = sys.exc_info()
|
|
81
116
|
_capture_exception(exc_info)
|
|
82
117
|
reraise(*exc_info)
|
|
83
118
|
|
|
84
119
|
return result
|
|
85
120
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
with sentry_sdk.start_span(
|
|
95
|
-
op=OP.QUEUE_SUBMIT_RAY,
|
|
96
|
-
name=qualname_from_function(f),
|
|
97
|
-
origin=RayIntegration.origin,
|
|
98
|
-
only_if_parent=True,
|
|
99
|
-
) as span:
|
|
100
|
-
tracing = {
|
|
101
|
-
k: v
|
|
102
|
-
for k, v in sentry_sdk.get_current_scope().iter_trace_propagation_headers()
|
|
103
|
-
}
|
|
104
|
-
try:
|
|
105
|
-
result = old_remote_method(*args, **kwargs, _tracing=tracing)
|
|
106
|
-
span.set_status(SPANSTATUS.OK)
|
|
107
|
-
except Exception:
|
|
108
|
-
span.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
109
|
-
exc_info = sys.exc_info()
|
|
110
|
-
_capture_exception(exc_info)
|
|
111
|
-
reraise(*exc_info)
|
|
112
|
-
|
|
113
|
-
return result
|
|
114
|
-
|
|
115
|
-
rv.remote = _remote_method_with_header_propagation
|
|
116
|
-
|
|
117
|
-
return rv
|
|
121
|
+
rv.remote = _remote_method_with_header_propagation
|
|
122
|
+
|
|
123
|
+
return rv
|
|
124
|
+
|
|
125
|
+
if f is not None:
|
|
126
|
+
return wrapper(f)
|
|
127
|
+
else:
|
|
128
|
+
return wrapper
|
|
118
129
|
|
|
119
130
|
ray.remote = new_remote
|
|
120
131
|
|
|
121
132
|
|
|
122
|
-
def _capture_exception(exc_info, **kwargs):
|
|
123
|
-
# type: (ExcInfo, **Any) -> None
|
|
133
|
+
def _capture_exception(exc_info: ExcInfo, **kwargs: Any) -> None:
|
|
124
134
|
client = sentry_sdk.get_client()
|
|
125
135
|
|
|
126
136
|
event, hint = event_from_exception(
|
|
@@ -139,8 +149,7 @@ class RayIntegration(Integration):
|
|
|
139
149
|
origin = f"auto.queue.{identifier}"
|
|
140
150
|
|
|
141
151
|
@staticmethod
|
|
142
|
-
def setup_once():
|
|
143
|
-
# type: () -> None
|
|
152
|
+
def setup_once() -> None:
|
|
144
153
|
version = package_version("ray")
|
|
145
154
|
_check_minimum_version(RayIntegration, version)
|
|
146
155
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
from sentry_sdk.integrations import Integration, DidNotEnable
|
|
2
3
|
from sentry_sdk.integrations.redis.consts import _DEFAULT_MAX_DATA_SIZE
|
|
3
4
|
from sentry_sdk.integrations.redis.rb import _patch_rb
|
|
@@ -15,14 +16,16 @@ if TYPE_CHECKING:
|
|
|
15
16
|
class RedisIntegration(Integration):
|
|
16
17
|
identifier = "redis"
|
|
17
18
|
|
|
18
|
-
def __init__(
|
|
19
|
-
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
max_data_size: int = _DEFAULT_MAX_DATA_SIZE,
|
|
22
|
+
cache_prefixes: Optional[list[str]] = None,
|
|
23
|
+
) -> None:
|
|
20
24
|
self.max_data_size = max_data_size
|
|
21
25
|
self.cache_prefixes = cache_prefixes if cache_prefixes is not None else []
|
|
22
26
|
|
|
23
27
|
@staticmethod
|
|
24
|
-
def setup_once():
|
|
25
|
-
# type: () -> None
|
|
28
|
+
def setup_once() -> None:
|
|
26
29
|
try:
|
|
27
30
|
from redis import StrictRedis, client
|
|
28
31
|
except ImportError:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sentry_sdk
|
|
2
3
|
from sentry_sdk.consts import OP
|
|
3
4
|
from sentry_sdk.integrations.redis.consts import SPAN_ORIGIN
|
|
@@ -24,15 +25,16 @@ if TYPE_CHECKING:
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
def patch_redis_async_pipeline(
|
|
27
|
-
pipeline_cls
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
pipeline_cls: Union[type[Pipeline[Any]], type[ClusterPipeline[Any]]],
|
|
29
|
+
is_cluster: bool,
|
|
30
|
+
get_command_args_fn: Any,
|
|
31
|
+
get_db_data_fn: Callable[[Any], dict[str, Any]],
|
|
32
|
+
) -> None:
|
|
30
33
|
old_execute = pipeline_cls.execute
|
|
31
34
|
|
|
32
35
|
from sentry_sdk.integrations.redis import RedisIntegration
|
|
33
36
|
|
|
34
|
-
async def _sentry_execute(self, *args, **kwargs):
|
|
35
|
-
# type: (Any, *Any, **Any) -> Any
|
|
37
|
+
async def _sentry_execute(self: Any, *args: Any, **kwargs: Any) -> Any:
|
|
36
38
|
if sentry_sdk.get_client().get_integration(RedisIntegration) is None:
|
|
37
39
|
return await old_execute(self, *args, **kwargs)
|
|
38
40
|
|
|
@@ -40,7 +42,7 @@ def patch_redis_async_pipeline(
|
|
|
40
42
|
op=OP.DB_REDIS,
|
|
41
43
|
name="redis.pipeline.execute",
|
|
42
44
|
origin=SPAN_ORIGIN,
|
|
43
|
-
|
|
45
|
+
only_as_child_span=True,
|
|
44
46
|
) as span:
|
|
45
47
|
with capture_internal_exceptions():
|
|
46
48
|
span_data = get_db_data_fn(self)
|
|
@@ -67,14 +69,18 @@ def patch_redis_async_pipeline(
|
|
|
67
69
|
pipeline_cls.execute = _sentry_execute # type: ignore
|
|
68
70
|
|
|
69
71
|
|
|
70
|
-
def patch_redis_async_client(
|
|
71
|
-
|
|
72
|
+
def patch_redis_async_client(
|
|
73
|
+
cls: Union[type[StrictRedis[Any]], type[RedisCluster[Any]]],
|
|
74
|
+
is_cluster: bool,
|
|
75
|
+
get_db_data_fn: Callable[[Any], dict[str, Any]],
|
|
76
|
+
) -> None:
|
|
72
77
|
old_execute_command = cls.execute_command
|
|
73
78
|
|
|
74
79
|
from sentry_sdk.integrations.redis import RedisIntegration
|
|
75
80
|
|
|
76
|
-
async def _sentry_execute_command(
|
|
77
|
-
|
|
81
|
+
async def _sentry_execute_command(
|
|
82
|
+
self: Any, name: str, *args: Any, **kwargs: Any
|
|
83
|
+
) -> Any:
|
|
78
84
|
integration = sentry_sdk.get_client().get_integration(RedisIntegration)
|
|
79
85
|
if integration is None:
|
|
80
86
|
return await old_execute_command(self, name, *args, **kwargs)
|
|
@@ -92,7 +98,7 @@ def patch_redis_async_client(cls, is_cluster, get_db_data_fn):
|
|
|
92
98
|
op=cache_properties["op"],
|
|
93
99
|
name=cache_properties["description"],
|
|
94
100
|
origin=SPAN_ORIGIN,
|
|
95
|
-
|
|
101
|
+
only_as_child_span=True,
|
|
96
102
|
)
|
|
97
103
|
cache_span.__enter__()
|
|
98
104
|
|
|
@@ -102,7 +108,7 @@ def patch_redis_async_client(cls, is_cluster, get_db_data_fn):
|
|
|
102
108
|
op=db_properties["op"],
|
|
103
109
|
name=db_properties["description"],
|
|
104
110
|
origin=SPAN_ORIGIN,
|
|
105
|
-
|
|
111
|
+
only_as_child_span=True,
|
|
106
112
|
)
|
|
107
113
|
db_span.__enter__()
|
|
108
114
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sentry_sdk
|
|
2
3
|
from sentry_sdk.consts import OP
|
|
3
4
|
from sentry_sdk.integrations.redis.consts import SPAN_ORIGIN
|
|
@@ -22,18 +23,16 @@ if TYPE_CHECKING:
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def patch_redis_pipeline(
|
|
25
|
-
pipeline_cls,
|
|
26
|
-
is_cluster,
|
|
27
|
-
get_command_args_fn,
|
|
28
|
-
get_db_data_fn,
|
|
29
|
-
):
|
|
30
|
-
# type: (Any, bool, Any, Callable[[Any], dict[str, Any]]) -> None
|
|
26
|
+
pipeline_cls: Any,
|
|
27
|
+
is_cluster: bool,
|
|
28
|
+
get_command_args_fn: Any,
|
|
29
|
+
get_db_data_fn: Callable[[Any], dict[str, Any]],
|
|
30
|
+
) -> None:
|
|
31
31
|
old_execute = pipeline_cls.execute
|
|
32
32
|
|
|
33
33
|
from sentry_sdk.integrations.redis import RedisIntegration
|
|
34
34
|
|
|
35
|
-
def sentry_patched_execute(self, *args, **kwargs):
|
|
36
|
-
# type: (Any, *Any, **Any) -> Any
|
|
35
|
+
def sentry_patched_execute(self: Any, *args: Any, **kwargs: Any) -> Any:
|
|
37
36
|
if sentry_sdk.get_client().get_integration(RedisIntegration) is None:
|
|
38
37
|
return old_execute(self, *args, **kwargs)
|
|
39
38
|
|
|
@@ -41,7 +40,7 @@ def patch_redis_pipeline(
|
|
|
41
40
|
op=OP.DB_REDIS,
|
|
42
41
|
name="redis.pipeline.execute",
|
|
43
42
|
origin=SPAN_ORIGIN,
|
|
44
|
-
|
|
43
|
+
only_as_child_span=True,
|
|
45
44
|
) as span:
|
|
46
45
|
with capture_internal_exceptions():
|
|
47
46
|
try:
|
|
@@ -64,8 +63,9 @@ def patch_redis_pipeline(
|
|
|
64
63
|
pipeline_cls.execute = sentry_patched_execute
|
|
65
64
|
|
|
66
65
|
|
|
67
|
-
def patch_redis_client(
|
|
68
|
-
|
|
66
|
+
def patch_redis_client(
|
|
67
|
+
cls: Any, is_cluster: bool, get_db_data_fn: Callable[[Any], dict[str, Any]]
|
|
68
|
+
) -> None:
|
|
69
69
|
"""
|
|
70
70
|
This function can be used to instrument custom redis client classes or
|
|
71
71
|
subclasses.
|
|
@@ -74,8 +74,9 @@ def patch_redis_client(cls, is_cluster, get_db_data_fn):
|
|
|
74
74
|
|
|
75
75
|
from sentry_sdk.integrations.redis import RedisIntegration
|
|
76
76
|
|
|
77
|
-
def sentry_patched_execute_command(
|
|
78
|
-
|
|
77
|
+
def sentry_patched_execute_command(
|
|
78
|
+
self: Any, name: str, *args: Any, **kwargs: Any
|
|
79
|
+
) -> Any:
|
|
79
80
|
integration = sentry_sdk.get_client().get_integration(RedisIntegration)
|
|
80
81
|
if integration is None:
|
|
81
82
|
return old_execute_command(self, name, *args, **kwargs)
|
|
@@ -93,7 +94,7 @@ def patch_redis_client(cls, is_cluster, get_db_data_fn):
|
|
|
93
94
|
op=cache_properties["op"],
|
|
94
95
|
name=cache_properties["description"],
|
|
95
96
|
origin=SPAN_ORIGIN,
|
|
96
|
-
|
|
97
|
+
only_as_child_span=True,
|
|
97
98
|
)
|
|
98
99
|
cache_span.__enter__()
|
|
99
100
|
|
|
@@ -103,7 +104,7 @@ def patch_redis_client(cls, is_cluster, get_db_data_fn):
|
|
|
103
104
|
op=db_properties["op"],
|
|
104
105
|
name=db_properties["description"],
|
|
105
106
|
origin=SPAN_ORIGIN,
|
|
106
|
-
|
|
107
|
+
only_as_child_span=True,
|
|
107
108
|
)
|
|
108
109
|
db_span.__enter__()
|
|
109
110
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Code used for the Caches module in Sentry
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
5
6
|
from sentry_sdk.consts import OP, SPANDATA
|
|
6
7
|
from sentry_sdk.integrations.redis.utils import _get_safe_key, _key_as_string
|
|
7
8
|
from sentry_sdk.utils import capture_internal_exceptions
|
|
@@ -16,8 +17,7 @@ if TYPE_CHECKING:
|
|
|
16
17
|
from typing import Any, Optional
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
def _get_op(name):
|
|
20
|
-
# type: (str) -> Optional[str]
|
|
20
|
+
def _get_op(name: str) -> Optional[str]:
|
|
21
21
|
op = None
|
|
22
22
|
if name.lower() in GET_COMMANDS:
|
|
23
23
|
op = OP.CACHE_GET
|
|
@@ -27,8 +27,12 @@ def _get_op(name):
|
|
|
27
27
|
return op
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def _compile_cache_span_properties(
|
|
31
|
-
|
|
30
|
+
def _compile_cache_span_properties(
|
|
31
|
+
redis_command: str,
|
|
32
|
+
args: tuple[Any, ...],
|
|
33
|
+
kwargs: dict[str, Any],
|
|
34
|
+
integration: RedisIntegration,
|
|
35
|
+
) -> dict[str, Any]:
|
|
32
36
|
key = _get_safe_key(redis_command, args, kwargs)
|
|
33
37
|
key_as_string = _key_as_string(key)
|
|
34
38
|
keys_as_string = key_as_string.split(", ")
|
|
@@ -61,8 +65,12 @@ def _compile_cache_span_properties(redis_command, args, kwargs, integration):
|
|
|
61
65
|
return properties
|
|
62
66
|
|
|
63
67
|
|
|
64
|
-
def _get_cache_span_description(
|
|
65
|
-
|
|
68
|
+
def _get_cache_span_description(
|
|
69
|
+
redis_command: str,
|
|
70
|
+
args: tuple[Any, ...],
|
|
71
|
+
kwargs: dict[str, Any],
|
|
72
|
+
integration: RedisIntegration,
|
|
73
|
+
) -> str:
|
|
66
74
|
description = _key_as_string(_get_safe_key(redis_command, args, kwargs))
|
|
67
75
|
|
|
68
76
|
data_should_be_truncated = (
|
|
@@ -74,8 +82,9 @@ def _get_cache_span_description(redis_command, args, kwargs, integration):
|
|
|
74
82
|
return description
|
|
75
83
|
|
|
76
84
|
|
|
77
|
-
def _get_cache_data(
|
|
78
|
-
|
|
85
|
+
def _get_cache_data(
|
|
86
|
+
redis_client: Any, properties: dict[str, Any], return_value: Optional[Any]
|
|
87
|
+
) -> dict[str, Any]:
|
|
79
88
|
data = {}
|
|
80
89
|
|
|
81
90
|
with capture_internal_exceptions():
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Code used for the Queries module in Sentry
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
5
6
|
from sentry_sdk.consts import OP, SPANDATA
|
|
6
7
|
from sentry_sdk.integrations.redis.utils import _get_safe_command
|
|
7
8
|
from sentry_sdk.utils import capture_internal_exceptions
|
|
@@ -14,8 +15,9 @@ if TYPE_CHECKING:
|
|
|
14
15
|
from typing import Any
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
def _compile_db_span_properties(
|
|
18
|
-
|
|
18
|
+
def _compile_db_span_properties(
|
|
19
|
+
integration: RedisIntegration, redis_command: str, args: tuple[Any, ...]
|
|
20
|
+
) -> dict[str, Any]:
|
|
19
21
|
description = _get_db_span_description(integration, redis_command, args)
|
|
20
22
|
|
|
21
23
|
properties = {
|
|
@@ -26,8 +28,9 @@ def _compile_db_span_properties(integration, redis_command, args):
|
|
|
26
28
|
return properties
|
|
27
29
|
|
|
28
30
|
|
|
29
|
-
def _get_db_span_description(
|
|
30
|
-
|
|
31
|
+
def _get_db_span_description(
|
|
32
|
+
integration: RedisIntegration, command_name: str, args: tuple[Any, ...]
|
|
33
|
+
) -> str:
|
|
31
34
|
description = command_name
|
|
32
35
|
|
|
33
36
|
with capture_internal_exceptions():
|
|
@@ -42,8 +45,7 @@ def _get_db_span_description(integration, command_name, args):
|
|
|
42
45
|
return description
|
|
43
46
|
|
|
44
47
|
|
|
45
|
-
def _get_connection_data(connection_params):
|
|
46
|
-
# type: (dict[str, Any]) -> dict[str, Any]
|
|
48
|
+
def _get_connection_data(connection_params: dict[str, Any]) -> dict[str, Any]:
|
|
47
49
|
data = {
|
|
48
50
|
SPANDATA.DB_SYSTEM: "redis",
|
|
49
51
|
}
|
|
@@ -63,8 +65,7 @@ def _get_connection_data(connection_params):
|
|
|
63
65
|
return data
|
|
64
66
|
|
|
65
67
|
|
|
66
|
-
def _get_db_data(redis_instance):
|
|
67
|
-
# type: (Redis[Any]) -> dict[str, Any]
|
|
68
|
+
def _get_db_data(redis_instance: Redis[Any]) -> dict[str, Any]:
|
|
68
69
|
try:
|
|
69
70
|
return _get_connection_data(redis_instance.connection_pool.connection_kwargs)
|
|
70
71
|
except AttributeError:
|
|
@@ -4,12 +4,13 @@ Instrumentation for Redis Blaster (rb)
|
|
|
4
4
|
https://github.com/getsentry/rb
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
7
9
|
from sentry_sdk.integrations.redis._sync_common import patch_redis_client
|
|
8
10
|
from sentry_sdk.integrations.redis.modules.queries import _get_db_data
|
|
9
11
|
|
|
10
12
|
|
|
11
|
-
def _patch_rb():
|
|
12
|
-
# type: () -> None
|
|
13
|
+
def _patch_rb() -> None:
|
|
13
14
|
try:
|
|
14
15
|
import rb.clients # type: ignore
|
|
15
16
|
except ImportError:
|
|
@@ -4,6 +4,8 @@ Instrumentation for Redis
|
|
|
4
4
|
https://github.com/redis/redis-py
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
7
9
|
from sentry_sdk.integrations.redis._sync_common import (
|
|
8
10
|
patch_redis_client,
|
|
9
11
|
patch_redis_pipeline,
|
|
@@ -16,13 +18,11 @@ if TYPE_CHECKING:
|
|
|
16
18
|
from typing import Any, Sequence
|
|
17
19
|
|
|
18
20
|
|
|
19
|
-
def _get_redis_command_args(command):
|
|
20
|
-
# type: (Any) -> Sequence[Any]
|
|
21
|
+
def _get_redis_command_args(command: Any) -> Sequence[Any]:
|
|
21
22
|
return command[0]
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
def _patch_redis(StrictRedis, client): # noqa: N803
|
|
25
|
-
# type: (Any, Any) -> None
|
|
25
|
+
def _patch_redis(StrictRedis: Any, client: Any) -> None: # noqa: N803
|
|
26
26
|
patch_redis_client(
|
|
27
27
|
StrictRedis,
|
|
28
28
|
is_cluster=False,
|
|
@@ -5,6 +5,8 @@ This is part of the main redis-py client.
|
|
|
5
5
|
https://github.com/redis/redis-py/blob/master/redis/cluster.py
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
8
10
|
from sentry_sdk.integrations.redis._sync_common import (
|
|
9
11
|
patch_redis_client,
|
|
10
12
|
patch_redis_pipeline,
|
|
@@ -25,8 +27,9 @@ if TYPE_CHECKING:
|
|
|
25
27
|
)
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
def _get_async_cluster_db_data(
|
|
29
|
-
|
|
30
|
+
def _get_async_cluster_db_data(
|
|
31
|
+
async_redis_cluster_instance: AsyncRedisCluster[Any],
|
|
32
|
+
) -> dict[str, Any]:
|
|
30
33
|
default_node = async_redis_cluster_instance.get_default_node()
|
|
31
34
|
if default_node is not None and default_node.connection_kwargs is not None:
|
|
32
35
|
return _get_connection_data(default_node.connection_kwargs)
|
|
@@ -34,8 +37,9 @@ def _get_async_cluster_db_data(async_redis_cluster_instance):
|
|
|
34
37
|
return {}
|
|
35
38
|
|
|
36
39
|
|
|
37
|
-
def _get_async_cluster_pipeline_db_data(
|
|
38
|
-
|
|
40
|
+
def _get_async_cluster_pipeline_db_data(
|
|
41
|
+
async_redis_cluster_pipeline_instance: AsyncClusterPipeline[Any],
|
|
42
|
+
) -> dict[str, Any]:
|
|
39
43
|
with capture_internal_exceptions():
|
|
40
44
|
client = getattr(async_redis_cluster_pipeline_instance, "cluster_client", None)
|
|
41
45
|
if client is None:
|
|
@@ -50,8 +54,7 @@ def _get_async_cluster_pipeline_db_data(async_redis_cluster_pipeline_instance):
|
|
|
50
54
|
return _get_async_cluster_db_data(client)
|
|
51
55
|
|
|
52
56
|
|
|
53
|
-
def _get_cluster_db_data(redis_cluster_instance):
|
|
54
|
-
# type: (RedisCluster[Any]) -> dict[str, Any]
|
|
57
|
+
def _get_cluster_db_data(redis_cluster_instance: RedisCluster[Any]) -> dict[str, Any]:
|
|
55
58
|
default_node = redis_cluster_instance.get_default_node()
|
|
56
59
|
|
|
57
60
|
if default_node is not None:
|
|
@@ -64,8 +67,7 @@ def _get_cluster_db_data(redis_cluster_instance):
|
|
|
64
67
|
return {}
|
|
65
68
|
|
|
66
69
|
|
|
67
|
-
def _patch_redis_cluster():
|
|
68
|
-
# type: () -> None
|
|
70
|
+
def _patch_redis_cluster() -> None:
|
|
69
71
|
"""Patches the cluster module on redis SDK (as opposed to rediscluster library)"""
|
|
70
72
|
try:
|
|
71
73
|
from redis import RedisCluster, cluster
|
|
@@ -5,6 +5,8 @@ The project redis-py-cluster is EOL and was integrated into redis-py starting fr
|
|
|
5
5
|
https://github.com/grokzen/redis-py-cluster
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
8
10
|
from sentry_sdk.integrations.redis._sync_common import (
|
|
9
11
|
patch_redis_client,
|
|
10
12
|
patch_redis_pipeline,
|
|
@@ -13,8 +15,7 @@ from sentry_sdk.integrations.redis.modules.queries import _get_db_data
|
|
|
13
15
|
from sentry_sdk.integrations.redis.utils import _parse_rediscluster_command
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
def _patch_rediscluster():
|
|
17
|
-
# type: () -> None
|
|
18
|
+
def _patch_rediscluster() -> None:
|
|
18
19
|
try:
|
|
19
20
|
import rediscluster # type: ignore
|
|
20
21
|
except ImportError:
|