sentry-sdk 3.0.0a1__py2.py3-none-any.whl → 3.0.0a3__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 +2 -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 +11 -18
- sentry_sdk/_werkzeug.py +5 -7
- sentry_sdk/ai/monitoring.py +44 -31
- sentry_sdk/ai/utils.py +3 -4
- sentry_sdk/api.py +75 -87
- sentry_sdk/attachments.py +10 -12
- sentry_sdk/client.py +137 -155
- sentry_sdk/consts.py +430 -174
- 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 +15 -18
- sentry_sdk/integrations/_wsgi_common.py +22 -33
- sentry_sdk/integrations/aiohttp.py +32 -30
- sentry_sdk/integrations/anthropic.py +42 -37
- sentry_sdk/integrations/argv.py +3 -4
- sentry_sdk/integrations/ariadne.py +16 -18
- sentry_sdk/integrations/arq.py +21 -29
- sentry_sdk/integrations/asgi.py +63 -37
- sentry_sdk/integrations/asyncio.py +14 -16
- 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 +18 -16
- sentry_sdk/integrations/bottle.py +25 -34
- sentry_sdk/integrations/celery/__init__.py +41 -61
- sentry_sdk/integrations/celery/beat.py +23 -27
- sentry_sdk/integrations/celery/utils.py +15 -17
- sentry_sdk/integrations/chalice.py +8 -10
- sentry_sdk/integrations/clickhouse_driver.py +21 -31
- sentry_sdk/integrations/cloud_resource_context.py +9 -16
- sentry_sdk/integrations/cohere.py +27 -33
- sentry_sdk/integrations/dedupe.py +5 -8
- sentry_sdk/integrations/django/__init__.py +57 -72
- sentry_sdk/integrations/django/asgi.py +26 -34
- sentry_sdk/integrations/django/caching.py +23 -19
- sentry_sdk/integrations/django/middleware.py +17 -20
- sentry_sdk/integrations/django/signals_handlers.py +11 -10
- sentry_sdk/integrations/django/templates.py +19 -16
- sentry_sdk/integrations/django/transactions.py +16 -11
- sentry_sdk/integrations/django/views.py +6 -10
- 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 +4 -6
- sentry_sdk/integrations/gql.py +16 -17
- sentry_sdk/integrations/graphene.py +13 -12
- sentry_sdk/integrations/grpc/__init__.py +19 -1
- sentry_sdk/integrations/grpc/aio/server.py +15 -14
- sentry_sdk/integrations/grpc/client.py +19 -9
- sentry_sdk/integrations/grpc/consts.py +2 -0
- sentry_sdk/integrations/grpc/server.py +12 -8
- sentry_sdk/integrations/httpx.py +9 -12
- sentry_sdk/integrations/huey.py +13 -20
- sentry_sdk/integrations/huggingface_hub.py +18 -18
- sentry_sdk/integrations/langchain.py +203 -113
- sentry_sdk/integrations/launchdarkly.py +13 -10
- sentry_sdk/integrations/litestar.py +37 -35
- sentry_sdk/integrations/logging.py +52 -65
- sentry_sdk/integrations/loguru.py +127 -57
- sentry_sdk/integrations/modules.py +3 -4
- sentry_sdk/integrations/openai.py +100 -88
- 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 +201 -0
- sentry_sdk/integrations/openfeature.py +11 -6
- sentry_sdk/integrations/pure_eval.py +6 -10
- sentry_sdk/integrations/pymongo.py +13 -17
- 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 +25 -12
- sentry_sdk/integrations/redis/_sync_common.py +19 -13
- 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 +21 -13
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
- sentry_sdk/integrations/redis/utils.py +23 -24
- sentry_sdk/integrations/rq.py +13 -16
- sentry_sdk/integrations/rust_tracing.py +9 -6
- sentry_sdk/integrations/sanic.py +34 -46
- sentry_sdk/integrations/serverless.py +22 -27
- sentry_sdk/integrations/socket.py +27 -15
- 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 +86 -90
- sentry_sdk/integrations/starlite.py +28 -34
- sentry_sdk/integrations/statsig.py +5 -4
- sentry_sdk/integrations/stdlib.py +28 -24
- sentry_sdk/integrations/strawberry.py +62 -49
- sentry_sdk/integrations/sys_exit.py +7 -11
- sentry_sdk/integrations/threading.py +12 -14
- 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 +41 -10
- sentry_sdk/monitor.py +16 -28
- sentry_sdk/opentelemetry/consts.py +11 -4
- sentry_sdk/opentelemetry/contextvars_context.py +26 -16
- sentry_sdk/opentelemetry/propagator.py +38 -21
- sentry_sdk/opentelemetry/sampler.py +51 -34
- sentry_sdk/opentelemetry/scope.py +36 -37
- sentry_sdk/opentelemetry/span_processor.py +48 -58
- sentry_sdk/opentelemetry/tracing.py +58 -14
- sentry_sdk/opentelemetry/utils.py +186 -194
- 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 -273
- sentry_sdk/scrubber.py +22 -26
- sentry_sdk/serializer.py +40 -54
- sentry_sdk/session.py +44 -61
- sentry_sdk/sessions.py +35 -49
- sentry_sdk/spotlight.py +15 -21
- sentry_sdk/tracing.py +121 -187
- sentry_sdk/tracing_utils.py +104 -122
- sentry_sdk/transport.py +131 -157
- sentry_sdk/utils.py +232 -309
- sentry_sdk/worker.py +16 -28
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/METADATA +3 -3
- sentry_sdk-3.0.0a3.dist-info/RECORD +168 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/WHEEL +1 -1
- sentry_sdk-3.0.0a1.dist-info/RECORD +0 -154
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/top_level.txt +0 -0
|
@@ -1,47 +1,43 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sys
|
|
2
3
|
from functools import wraps
|
|
3
4
|
|
|
4
5
|
import sentry_sdk
|
|
5
6
|
from sentry_sdk.utils import event_from_exception, reraise
|
|
6
7
|
|
|
7
|
-
from typing import TYPE_CHECKING
|
|
8
|
+
from typing import TYPE_CHECKING, overload
|
|
8
9
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
10
|
-
from typing import
|
|
11
|
+
from typing import NoReturn
|
|
11
12
|
from typing import Callable
|
|
12
13
|
from typing import TypeVar
|
|
14
|
+
from typing import ParamSpec
|
|
13
15
|
from typing import Union
|
|
14
16
|
from typing import Optional
|
|
15
|
-
from typing import overload
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
T = TypeVar("T")
|
|
19
|
+
P = ParamSpec("P")
|
|
18
20
|
|
|
19
|
-
else:
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
# type: (F) -> F
|
|
23
|
-
return x
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@overload
|
|
27
|
-
def serverless_function(f, flush=True):
|
|
28
|
-
# type: (F, bool) -> F
|
|
29
|
-
pass
|
|
22
|
+
if TYPE_CHECKING:
|
|
30
23
|
|
|
24
|
+
@overload
|
|
25
|
+
def serverless_function(f: Callable[P, T], flush: bool = True) -> Callable[P, T]:
|
|
26
|
+
pass
|
|
31
27
|
|
|
32
|
-
@overload
|
|
33
|
-
def serverless_function(
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
@overload
|
|
29
|
+
def serverless_function(
|
|
30
|
+
f: None = None, flush: bool = True
|
|
31
|
+
) -> Callable[[Callable[P, T]], Callable[P, T]]:
|
|
32
|
+
pass
|
|
36
33
|
|
|
37
34
|
|
|
38
|
-
def serverless_function(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
def serverless_function(
|
|
36
|
+
f: Optional[Callable[P, T]] = None, flush: bool = True
|
|
37
|
+
) -> Union[Callable[P, T], Callable[[Callable[P, T]], Callable[P, T]]]:
|
|
38
|
+
def wrapper(f: Callable[P, T]) -> Callable[P, T]:
|
|
42
39
|
@wraps(f)
|
|
43
|
-
def inner(*args, **kwargs):
|
|
44
|
-
# type: (*Any, **Any) -> Any
|
|
40
|
+
def inner(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
45
41
|
with sentry_sdk.isolation_scope() as scope:
|
|
46
42
|
scope.clear_breadcrumbs()
|
|
47
43
|
|
|
@@ -53,7 +49,7 @@ def serverless_function(f=None, flush=True): # noqa
|
|
|
53
49
|
if flush:
|
|
54
50
|
sentry_sdk.flush()
|
|
55
51
|
|
|
56
|
-
return inner
|
|
52
|
+
return inner
|
|
57
53
|
|
|
58
54
|
if f is None:
|
|
59
55
|
return wrapper
|
|
@@ -61,8 +57,7 @@ def serverless_function(f=None, flush=True): # noqa
|
|
|
61
57
|
return wrapper(f)
|
|
62
58
|
|
|
63
59
|
|
|
64
|
-
def _capture_and_reraise():
|
|
65
|
-
# type: () -> None
|
|
60
|
+
def _capture_and_reraise() -> NoReturn:
|
|
66
61
|
exc_info = sys.exc_info()
|
|
67
62
|
client = sentry_sdk.get_client()
|
|
68
63
|
if client.is_active():
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import socket
|
|
2
3
|
|
|
3
4
|
import sentry_sdk
|
|
@@ -17,8 +18,7 @@ class SocketIntegration(Integration):
|
|
|
17
18
|
origin = f"auto.socket.{identifier}"
|
|
18
19
|
|
|
19
20
|
@staticmethod
|
|
20
|
-
def setup_once():
|
|
21
|
-
# type: () -> None
|
|
21
|
+
def setup_once() -> None:
|
|
22
22
|
"""
|
|
23
23
|
patches two of the most used functions of socket: create_connection and getaddrinfo(dns resolver)
|
|
24
24
|
"""
|
|
@@ -26,8 +26,9 @@ class SocketIntegration(Integration):
|
|
|
26
26
|
_patch_getaddrinfo()
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
def _get_span_description(
|
|
30
|
-
|
|
29
|
+
def _get_span_description(
|
|
30
|
+
host: Union[bytes, str, None], port: Union[bytes, str, int, None]
|
|
31
|
+
) -> str:
|
|
31
32
|
|
|
32
33
|
try:
|
|
33
34
|
host = host.decode() # type: ignore
|
|
@@ -43,16 +44,14 @@ def _get_span_description(host, port):
|
|
|
43
44
|
return description
|
|
44
45
|
|
|
45
46
|
|
|
46
|
-
def _patch_create_connection():
|
|
47
|
-
# type: () -> None
|
|
47
|
+
def _patch_create_connection() -> None:
|
|
48
48
|
real_create_connection = socket.create_connection
|
|
49
49
|
|
|
50
50
|
def create_connection(
|
|
51
|
-
address,
|
|
52
|
-
timeout=socket._GLOBAL_DEFAULT_TIMEOUT, # type: ignore
|
|
53
|
-
source_address=None,
|
|
54
|
-
):
|
|
55
|
-
# type: (Tuple[Optional[str], int], Optional[float], Optional[Tuple[Union[bytearray, bytes, str], int]])-> socket.socket
|
|
51
|
+
address: Tuple[Optional[str], int],
|
|
52
|
+
timeout: Optional[float] = socket._GLOBAL_DEFAULT_TIMEOUT, # type: ignore
|
|
53
|
+
source_address: Optional[Tuple[Union[bytearray, bytes, str], int]] = None,
|
|
54
|
+
) -> socket.socket:
|
|
56
55
|
integration = sentry_sdk.get_client().get_integration(SocketIntegration)
|
|
57
56
|
if integration is None:
|
|
58
57
|
return real_create_connection(address, timeout, source_address)
|
|
@@ -76,12 +75,25 @@ def _patch_create_connection():
|
|
|
76
75
|
socket.create_connection = create_connection # type: ignore
|
|
77
76
|
|
|
78
77
|
|
|
79
|
-
def _patch_getaddrinfo():
|
|
80
|
-
# type: () -> None
|
|
78
|
+
def _patch_getaddrinfo() -> None:
|
|
81
79
|
real_getaddrinfo = socket.getaddrinfo
|
|
82
80
|
|
|
83
|
-
def getaddrinfo(
|
|
84
|
-
|
|
81
|
+
def getaddrinfo(
|
|
82
|
+
host: Union[bytes, str, None],
|
|
83
|
+
port: Union[bytes, str, int, None],
|
|
84
|
+
family: int = 0,
|
|
85
|
+
type: int = 0,
|
|
86
|
+
proto: int = 0,
|
|
87
|
+
flags: int = 0,
|
|
88
|
+
) -> List[
|
|
89
|
+
Tuple[
|
|
90
|
+
AddressFamily,
|
|
91
|
+
SocketKind,
|
|
92
|
+
int,
|
|
93
|
+
str,
|
|
94
|
+
Union[Tuple[str, int], Tuple[str, int, int, int], Tuple[int, bytes]],
|
|
95
|
+
]
|
|
96
|
+
]:
|
|
85
97
|
integration = sentry_sdk.get_client().get_integration(SocketIntegration)
|
|
86
98
|
if integration is None:
|
|
87
99
|
return real_getaddrinfo(host, port, family, type, proto, flags)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sentry_sdk
|
|
2
3
|
from sentry_sdk.integrations import Integration
|
|
3
4
|
from sentry_sdk.utils import capture_internal_exceptions, ensure_integration_enabled
|
|
@@ -16,13 +17,11 @@ class SparkIntegration(Integration):
|
|
|
16
17
|
identifier = "spark"
|
|
17
18
|
|
|
18
19
|
@staticmethod
|
|
19
|
-
def setup_once():
|
|
20
|
-
# type: () -> None
|
|
20
|
+
def setup_once() -> None:
|
|
21
21
|
_setup_sentry_tracing()
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def _set_app_properties():
|
|
25
|
-
# type: () -> None
|
|
24
|
+
def _set_app_properties() -> None:
|
|
26
25
|
"""
|
|
27
26
|
Set properties in driver that propagate to worker processes, allowing for workers to have access to those properties.
|
|
28
27
|
This allows worker integration to have access to app_name and application_id.
|
|
@@ -41,8 +40,7 @@ def _set_app_properties():
|
|
|
41
40
|
)
|
|
42
41
|
|
|
43
42
|
|
|
44
|
-
def _start_sentry_listener(sc):
|
|
45
|
-
# type: (SparkContext) -> None
|
|
43
|
+
def _start_sentry_listener(sc: SparkContext) -> None:
|
|
46
44
|
"""
|
|
47
45
|
Start java gateway server to add custom `SparkListener`
|
|
48
46
|
"""
|
|
@@ -54,13 +52,11 @@ def _start_sentry_listener(sc):
|
|
|
54
52
|
sc._jsc.sc().addSparkListener(listener)
|
|
55
53
|
|
|
56
54
|
|
|
57
|
-
def _add_event_processor(sc):
|
|
58
|
-
# type: (SparkContext) -> None
|
|
55
|
+
def _add_event_processor(sc: SparkContext) -> None:
|
|
59
56
|
scope = sentry_sdk.get_isolation_scope()
|
|
60
57
|
|
|
61
58
|
@scope.add_event_processor
|
|
62
|
-
def process_event(event, hint):
|
|
63
|
-
# type: (Event, Hint) -> Optional[Event]
|
|
59
|
+
def process_event(event: Event, hint: Hint) -> Optional[Event]:
|
|
64
60
|
with capture_internal_exceptions():
|
|
65
61
|
if sentry_sdk.get_client().get_integration(SparkIntegration) is None:
|
|
66
62
|
return event
|
|
@@ -90,23 +86,22 @@ def _add_event_processor(sc):
|
|
|
90
86
|
return event
|
|
91
87
|
|
|
92
88
|
|
|
93
|
-
def _activate_integration(sc):
|
|
94
|
-
# type: (SparkContext) -> None
|
|
89
|
+
def _activate_integration(sc: SparkContext) -> None:
|
|
95
90
|
|
|
96
91
|
_start_sentry_listener(sc)
|
|
97
92
|
_set_app_properties()
|
|
98
93
|
_add_event_processor(sc)
|
|
99
94
|
|
|
100
95
|
|
|
101
|
-
def _patch_spark_context_init():
|
|
102
|
-
# type: () -> None
|
|
96
|
+
def _patch_spark_context_init() -> None:
|
|
103
97
|
from pyspark import SparkContext
|
|
104
98
|
|
|
105
99
|
spark_context_init = SparkContext._do_init
|
|
106
100
|
|
|
107
101
|
@ensure_integration_enabled(SparkIntegration, spark_context_init)
|
|
108
|
-
def _sentry_patched_spark_context_init(
|
|
109
|
-
|
|
102
|
+
def _sentry_patched_spark_context_init(
|
|
103
|
+
self: SparkContext, *args: Any, **kwargs: Any
|
|
104
|
+
) -> Optional[Any]:
|
|
110
105
|
rv = spark_context_init(self, *args, **kwargs)
|
|
111
106
|
_activate_integration(self)
|
|
112
107
|
return rv
|
|
@@ -114,8 +109,7 @@ def _patch_spark_context_init():
|
|
|
114
109
|
SparkContext._do_init = _sentry_patched_spark_context_init
|
|
115
110
|
|
|
116
111
|
|
|
117
|
-
def _setup_sentry_tracing():
|
|
118
|
-
# type: () -> None
|
|
112
|
+
def _setup_sentry_tracing() -> None:
|
|
119
113
|
from pyspark import SparkContext
|
|
120
114
|
|
|
121
115
|
if SparkContext._active_spark_context is not None:
|
|
@@ -125,102 +119,76 @@ def _setup_sentry_tracing():
|
|
|
125
119
|
|
|
126
120
|
|
|
127
121
|
class SparkListener:
|
|
128
|
-
def onApplicationEnd(self, applicationEnd
|
|
129
|
-
# type: (Any) -> None
|
|
122
|
+
def onApplicationEnd(self, applicationEnd: Any) -> None:
|
|
130
123
|
pass
|
|
131
124
|
|
|
132
|
-
def onApplicationStart(self, applicationStart
|
|
133
|
-
# type: (Any) -> None
|
|
125
|
+
def onApplicationStart(self, applicationStart: Any) -> None:
|
|
134
126
|
pass
|
|
135
127
|
|
|
136
|
-
def onBlockManagerAdded(self, blockManagerAdded
|
|
137
|
-
# type: (Any) -> None
|
|
128
|
+
def onBlockManagerAdded(self, blockManagerAdded: Any) -> None:
|
|
138
129
|
pass
|
|
139
130
|
|
|
140
|
-
def onBlockManagerRemoved(self, blockManagerRemoved
|
|
141
|
-
# type: (Any) -> None
|
|
131
|
+
def onBlockManagerRemoved(self, blockManagerRemoved: Any) -> None:
|
|
142
132
|
pass
|
|
143
133
|
|
|
144
|
-
def onBlockUpdated(self, blockUpdated
|
|
145
|
-
# type: (Any) -> None
|
|
134
|
+
def onBlockUpdated(self, blockUpdated: Any) -> None:
|
|
146
135
|
pass
|
|
147
136
|
|
|
148
|
-
def onEnvironmentUpdate(self, environmentUpdate
|
|
149
|
-
# type: (Any) -> None
|
|
137
|
+
def onEnvironmentUpdate(self, environmentUpdate: Any) -> None:
|
|
150
138
|
pass
|
|
151
139
|
|
|
152
|
-
def onExecutorAdded(self, executorAdded
|
|
153
|
-
# type: (Any) -> None
|
|
140
|
+
def onExecutorAdded(self, executorAdded: Any) -> None:
|
|
154
141
|
pass
|
|
155
142
|
|
|
156
|
-
def onExecutorBlacklisted(self, executorBlacklisted
|
|
157
|
-
# type: (Any) -> None
|
|
143
|
+
def onExecutorBlacklisted(self, executorBlacklisted: Any) -> None:
|
|
158
144
|
pass
|
|
159
145
|
|
|
160
|
-
def onExecutorBlacklistedForStage(
|
|
161
|
-
self, executorBlacklistedForStage # noqa: N803
|
|
162
|
-
):
|
|
163
|
-
# type: (Any) -> None
|
|
146
|
+
def onExecutorBlacklistedForStage(self, executorBlacklistedForStage: Any) -> None:
|
|
164
147
|
pass
|
|
165
148
|
|
|
166
|
-
def onExecutorMetricsUpdate(self, executorMetricsUpdate
|
|
167
|
-
# type: (Any) -> None
|
|
149
|
+
def onExecutorMetricsUpdate(self, executorMetricsUpdate: Any) -> None:
|
|
168
150
|
pass
|
|
169
151
|
|
|
170
|
-
def onExecutorRemoved(self, executorRemoved
|
|
171
|
-
# type: (Any) -> None
|
|
152
|
+
def onExecutorRemoved(self, executorRemoved: Any) -> None:
|
|
172
153
|
pass
|
|
173
154
|
|
|
174
|
-
def onJobEnd(self, jobEnd
|
|
175
|
-
# type: (Any) -> None
|
|
155
|
+
def onJobEnd(self, jobEnd: Any) -> None:
|
|
176
156
|
pass
|
|
177
157
|
|
|
178
|
-
def onJobStart(self, jobStart
|
|
179
|
-
# type: (Any) -> None
|
|
158
|
+
def onJobStart(self, jobStart: Any) -> None:
|
|
180
159
|
pass
|
|
181
160
|
|
|
182
|
-
def onNodeBlacklisted(self, nodeBlacklisted
|
|
183
|
-
# type: (Any) -> None
|
|
161
|
+
def onNodeBlacklisted(self, nodeBlacklisted: Any) -> None:
|
|
184
162
|
pass
|
|
185
163
|
|
|
186
|
-
def onNodeBlacklistedForStage(self, nodeBlacklistedForStage
|
|
187
|
-
# type: (Any) -> None
|
|
164
|
+
def onNodeBlacklistedForStage(self, nodeBlacklistedForStage: Any) -> None:
|
|
188
165
|
pass
|
|
189
166
|
|
|
190
|
-
def onNodeUnblacklisted(self, nodeUnblacklisted
|
|
191
|
-
# type: (Any) -> None
|
|
167
|
+
def onNodeUnblacklisted(self, nodeUnblacklisted: Any) -> None:
|
|
192
168
|
pass
|
|
193
169
|
|
|
194
|
-
def onOtherEvent(self, event
|
|
195
|
-
# type: (Any) -> None
|
|
170
|
+
def onOtherEvent(self, event: Any) -> None:
|
|
196
171
|
pass
|
|
197
172
|
|
|
198
|
-
def onSpeculativeTaskSubmitted(self, speculativeTask
|
|
199
|
-
# type: (Any) -> None
|
|
173
|
+
def onSpeculativeTaskSubmitted(self, speculativeTask: Any) -> None:
|
|
200
174
|
pass
|
|
201
175
|
|
|
202
|
-
def onStageCompleted(self, stageCompleted
|
|
203
|
-
# type: (Any) -> None
|
|
176
|
+
def onStageCompleted(self, stageCompleted: Any) -> None:
|
|
204
177
|
pass
|
|
205
178
|
|
|
206
|
-
def onStageSubmitted(self, stageSubmitted
|
|
207
|
-
# type: (Any) -> None
|
|
179
|
+
def onStageSubmitted(self, stageSubmitted: Any) -> None:
|
|
208
180
|
pass
|
|
209
181
|
|
|
210
|
-
def onTaskEnd(self, taskEnd
|
|
211
|
-
# type: (Any) -> None
|
|
182
|
+
def onTaskEnd(self, taskEnd: Any) -> None:
|
|
212
183
|
pass
|
|
213
184
|
|
|
214
|
-
def onTaskGettingResult(self, taskGettingResult
|
|
215
|
-
# type: (Any) -> None
|
|
185
|
+
def onTaskGettingResult(self, taskGettingResult: Any) -> None:
|
|
216
186
|
pass
|
|
217
187
|
|
|
218
|
-
def onTaskStart(self, taskStart
|
|
219
|
-
# type: (Any) -> None
|
|
188
|
+
def onTaskStart(self, taskStart: Any) -> None:
|
|
220
189
|
pass
|
|
221
190
|
|
|
222
|
-
def onUnpersistRDD(self, unpersistRDD
|
|
223
|
-
# type: (Any) -> None
|
|
191
|
+
def onUnpersistRDD(self, unpersistRDD: Any) -> None:
|
|
224
192
|
pass
|
|
225
193
|
|
|
226
194
|
class Java:
|
|
@@ -230,25 +198,22 @@ class SparkListener:
|
|
|
230
198
|
class SentryListener(SparkListener):
|
|
231
199
|
def _add_breadcrumb(
|
|
232
200
|
self,
|
|
233
|
-
level
|
|
234
|
-
message
|
|
235
|
-
data
|
|
236
|
-
):
|
|
237
|
-
# type: (...) -> None
|
|
201
|
+
level: str,
|
|
202
|
+
message: str,
|
|
203
|
+
data: Optional[dict[str, Any]] = None,
|
|
204
|
+
) -> None:
|
|
238
205
|
sentry_sdk.get_isolation_scope().add_breadcrumb(
|
|
239
206
|
level=level, message=message, data=data
|
|
240
207
|
)
|
|
241
208
|
|
|
242
|
-
def onJobStart(self, jobStart
|
|
243
|
-
# type: (Any) -> None
|
|
209
|
+
def onJobStart(self, jobStart: Any) -> None:
|
|
244
210
|
sentry_sdk.get_isolation_scope().clear_breadcrumbs()
|
|
245
211
|
|
|
246
212
|
message = "Job {} Started".format(jobStart.jobId())
|
|
247
213
|
self._add_breadcrumb(level="info", message=message)
|
|
248
214
|
_set_app_properties()
|
|
249
215
|
|
|
250
|
-
def onJobEnd(self, jobEnd
|
|
251
|
-
# type: (Any) -> None
|
|
216
|
+
def onJobEnd(self, jobEnd: Any) -> None:
|
|
252
217
|
level = ""
|
|
253
218
|
message = ""
|
|
254
219
|
data = {"result": jobEnd.jobResult().toString()}
|
|
@@ -262,8 +227,7 @@ class SentryListener(SparkListener):
|
|
|
262
227
|
|
|
263
228
|
self._add_breadcrumb(level=level, message=message, data=data)
|
|
264
229
|
|
|
265
|
-
def onStageSubmitted(self, stageSubmitted
|
|
266
|
-
# type: (Any) -> None
|
|
230
|
+
def onStageSubmitted(self, stageSubmitted: Any) -> None:
|
|
267
231
|
stage_info = stageSubmitted.stageInfo()
|
|
268
232
|
message = "Stage {} Submitted".format(stage_info.stageId())
|
|
269
233
|
|
|
@@ -275,8 +239,7 @@ class SentryListener(SparkListener):
|
|
|
275
239
|
self._add_breadcrumb(level="info", message=message, data=data)
|
|
276
240
|
_set_app_properties()
|
|
277
241
|
|
|
278
|
-
def onStageCompleted(self, stageCompleted
|
|
279
|
-
# type: (Any) -> None
|
|
242
|
+
def onStageCompleted(self, stageCompleted: Any) -> None:
|
|
280
243
|
from py4j.protocol import Py4JJavaError # type: ignore
|
|
281
244
|
|
|
282
245
|
stage_info = stageCompleted.stageInfo()
|
|
@@ -300,8 +263,7 @@ class SentryListener(SparkListener):
|
|
|
300
263
|
self._add_breadcrumb(level=level, message=message, data=data)
|
|
301
264
|
|
|
302
265
|
|
|
303
|
-
def _get_attempt_id(stage_info):
|
|
304
|
-
# type: (Any) -> Optional[int]
|
|
266
|
+
def _get_attempt_id(stage_info: Any) -> Optional[int]:
|
|
305
267
|
try:
|
|
306
268
|
return stage_info.attemptId()
|
|
307
269
|
except Exception:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sys
|
|
2
3
|
|
|
3
4
|
import sentry_sdk
|
|
@@ -23,15 +24,13 @@ class SparkWorkerIntegration(Integration):
|
|
|
23
24
|
identifier = "spark_worker"
|
|
24
25
|
|
|
25
26
|
@staticmethod
|
|
26
|
-
def setup_once():
|
|
27
|
-
# type: () -> None
|
|
27
|
+
def setup_once() -> None:
|
|
28
28
|
import pyspark.daemon as original_daemon
|
|
29
29
|
|
|
30
30
|
original_daemon.worker_main = _sentry_worker_main
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def _capture_exception(exc_info):
|
|
34
|
-
# type: (ExcInfo) -> None
|
|
33
|
+
def _capture_exception(exc_info: ExcInfo) -> None:
|
|
35
34
|
client = sentry_sdk.get_client()
|
|
36
35
|
|
|
37
36
|
mechanism = {"type": "spark", "handled": False}
|
|
@@ -53,22 +52,20 @@ def _capture_exception(exc_info):
|
|
|
53
52
|
if rv:
|
|
54
53
|
rv.reverse()
|
|
55
54
|
hint = event_hint_with_exc_info(exc_info)
|
|
56
|
-
event = {"level": "error", "exception": {"values": rv}}
|
|
55
|
+
event: Event = {"level": "error", "exception": {"values": rv}}
|
|
57
56
|
|
|
58
57
|
_tag_task_context()
|
|
59
58
|
|
|
60
59
|
sentry_sdk.capture_event(event, hint=hint)
|
|
61
60
|
|
|
62
61
|
|
|
63
|
-
def _tag_task_context():
|
|
64
|
-
# type: () -> None
|
|
62
|
+
def _tag_task_context() -> None:
|
|
65
63
|
from pyspark.taskcontext import TaskContext
|
|
66
64
|
|
|
67
65
|
scope = sentry_sdk.get_isolation_scope()
|
|
68
66
|
|
|
69
67
|
@scope.add_event_processor
|
|
70
|
-
def process_event(event, hint):
|
|
71
|
-
# type: (Event, Hint) -> Optional[Event]
|
|
68
|
+
def process_event(event: Event, hint: Hint) -> Optional[Event]:
|
|
72
69
|
with capture_internal_exceptions():
|
|
73
70
|
integration = sentry_sdk.get_client().get_integration(
|
|
74
71
|
SparkWorkerIntegration
|
|
@@ -103,8 +100,7 @@ def _tag_task_context():
|
|
|
103
100
|
return event
|
|
104
101
|
|
|
105
102
|
|
|
106
|
-
def _sentry_worker_main(*args, **kwargs):
|
|
107
|
-
# type: (*Optional[Any], **Optional[Any]) -> None
|
|
103
|
+
def _sentry_worker_main(*args: Optional[Any], **kwargs: Optional[Any]) -> None:
|
|
108
104
|
import pyspark.worker as original_worker
|
|
109
105
|
|
|
110
106
|
try:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
from sentry_sdk.consts import SPANSTATUS, SPANDATA
|
|
2
3
|
from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable
|
|
3
4
|
from sentry_sdk.tracing_utils import add_query_source, record_sql_queries
|
|
@@ -29,8 +30,7 @@ class SqlalchemyIntegration(Integration):
|
|
|
29
30
|
origin = f"auto.db.{identifier}"
|
|
30
31
|
|
|
31
32
|
@staticmethod
|
|
32
|
-
def setup_once():
|
|
33
|
-
# type: () -> None
|
|
33
|
+
def setup_once() -> None:
|
|
34
34
|
version = parse_version(SQLALCHEMY_VERSION)
|
|
35
35
|
_check_minimum_version(SqlalchemyIntegration, version)
|
|
36
36
|
|
|
@@ -41,9 +41,14 @@ class SqlalchemyIntegration(Integration):
|
|
|
41
41
|
|
|
42
42
|
@ensure_integration_enabled(SqlalchemyIntegration)
|
|
43
43
|
def _before_cursor_execute(
|
|
44
|
-
conn
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
conn: Any,
|
|
45
|
+
cursor: Any,
|
|
46
|
+
statement: Any,
|
|
47
|
+
parameters: Any,
|
|
48
|
+
context: Any,
|
|
49
|
+
executemany: bool,
|
|
50
|
+
*args: Any,
|
|
51
|
+
) -> None:
|
|
47
52
|
ctx_mgr = record_sql_queries(
|
|
48
53
|
cursor,
|
|
49
54
|
statement,
|
|
@@ -62,13 +67,14 @@ def _before_cursor_execute(
|
|
|
62
67
|
|
|
63
68
|
|
|
64
69
|
@ensure_integration_enabled(SqlalchemyIntegration)
|
|
65
|
-
def _after_cursor_execute(
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
def _after_cursor_execute(
|
|
71
|
+
conn: Any, cursor: Any, statement: Any, parameters: Any, context: Any, *args: Any
|
|
72
|
+
) -> None:
|
|
73
|
+
ctx_mgr: Optional[ContextManager[Any]] = getattr(
|
|
68
74
|
context, "_sentry_sql_span_manager", None
|
|
69
|
-
)
|
|
75
|
+
)
|
|
70
76
|
|
|
71
|
-
span = getattr(context, "_sentry_sql_span", None)
|
|
77
|
+
span: Optional[Span] = getattr(context, "_sentry_sql_span", None)
|
|
72
78
|
if span is not None:
|
|
73
79
|
with capture_internal_exceptions():
|
|
74
80
|
add_query_source(span)
|
|
@@ -78,13 +84,12 @@ def _after_cursor_execute(conn, cursor, statement, parameters, context, *args):
|
|
|
78
84
|
ctx_mgr.__exit__(None, None, None)
|
|
79
85
|
|
|
80
86
|
|
|
81
|
-
def _handle_error(context, *args):
|
|
82
|
-
# type: (Any, *Any) -> None
|
|
87
|
+
def _handle_error(context: Any, *args: Any) -> None:
|
|
83
88
|
execution_context = context.execution_context
|
|
84
89
|
if execution_context is None:
|
|
85
90
|
return
|
|
86
91
|
|
|
87
|
-
span = getattr(execution_context, "_sentry_sql_span", None)
|
|
92
|
+
span: Optional[Span] = getattr(execution_context, "_sentry_sql_span", None)
|
|
88
93
|
|
|
89
94
|
if span is not None:
|
|
90
95
|
span.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
@@ -92,9 +97,9 @@ def _handle_error(context, *args):
|
|
|
92
97
|
# _after_cursor_execute does not get called for crashing SQL stmts. Judging
|
|
93
98
|
# from SQLAlchemy codebase it does seem like any error coming into this
|
|
94
99
|
# handler is going to be fatal.
|
|
95
|
-
ctx_mgr = getattr(
|
|
100
|
+
ctx_mgr: Optional[ContextManager[Any]] = getattr(
|
|
96
101
|
execution_context, "_sentry_sql_span_manager", None
|
|
97
|
-
)
|
|
102
|
+
)
|
|
98
103
|
|
|
99
104
|
if ctx_mgr is not None:
|
|
100
105
|
execution_context._sentry_sql_span_manager = None
|
|
@@ -102,8 +107,7 @@ def _handle_error(context, *args):
|
|
|
102
107
|
|
|
103
108
|
|
|
104
109
|
# See: https://docs.sqlalchemy.org/en/20/dialects/index.html
|
|
105
|
-
def _get_db_system(name):
|
|
106
|
-
# type: (str) -> Optional[str]
|
|
110
|
+
def _get_db_system(name: str) -> Optional[str]:
|
|
107
111
|
name = str(name)
|
|
108
112
|
|
|
109
113
|
if "sqlite" in name:
|
|
@@ -124,8 +128,7 @@ def _get_db_system(name):
|
|
|
124
128
|
return None
|
|
125
129
|
|
|
126
130
|
|
|
127
|
-
def _set_db_data(span, conn):
|
|
128
|
-
# type: (Span, Any) -> None
|
|
131
|
+
def _set_db_data(span: Span, conn: Any) -> None:
|
|
129
132
|
db_system = _get_db_system(conn.engine.name)
|
|
130
133
|
if db_system is not None:
|
|
131
134
|
span.set_attribute(SPANDATA.DB_SYSTEM, db_system)
|