sentry-sdk 0.7.5__py2.py3-none-any.whl → 2.46.0__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.
Files changed (193) hide show
  1. sentry_sdk/__init__.py +48 -30
  2. sentry_sdk/_compat.py +74 -61
  3. sentry_sdk/_init_implementation.py +84 -0
  4. sentry_sdk/_log_batcher.py +172 -0
  5. sentry_sdk/_lru_cache.py +47 -0
  6. sentry_sdk/_metrics_batcher.py +167 -0
  7. sentry_sdk/_queue.py +289 -0
  8. sentry_sdk/_types.py +338 -0
  9. sentry_sdk/_werkzeug.py +98 -0
  10. sentry_sdk/ai/__init__.py +7 -0
  11. sentry_sdk/ai/monitoring.py +137 -0
  12. sentry_sdk/ai/utils.py +144 -0
  13. sentry_sdk/api.py +496 -80
  14. sentry_sdk/attachments.py +75 -0
  15. sentry_sdk/client.py +1023 -103
  16. sentry_sdk/consts.py +1438 -66
  17. sentry_sdk/crons/__init__.py +10 -0
  18. sentry_sdk/crons/api.py +62 -0
  19. sentry_sdk/crons/consts.py +4 -0
  20. sentry_sdk/crons/decorator.py +135 -0
  21. sentry_sdk/debug.py +15 -14
  22. sentry_sdk/envelope.py +369 -0
  23. sentry_sdk/feature_flags.py +71 -0
  24. sentry_sdk/hub.py +611 -280
  25. sentry_sdk/integrations/__init__.py +276 -49
  26. sentry_sdk/integrations/_asgi_common.py +108 -0
  27. sentry_sdk/integrations/_wsgi_common.py +180 -44
  28. sentry_sdk/integrations/aiohttp.py +291 -42
  29. sentry_sdk/integrations/anthropic.py +439 -0
  30. sentry_sdk/integrations/argv.py +9 -8
  31. sentry_sdk/integrations/ariadne.py +161 -0
  32. sentry_sdk/integrations/arq.py +247 -0
  33. sentry_sdk/integrations/asgi.py +341 -0
  34. sentry_sdk/integrations/asyncio.py +144 -0
  35. sentry_sdk/integrations/asyncpg.py +208 -0
  36. sentry_sdk/integrations/atexit.py +17 -10
  37. sentry_sdk/integrations/aws_lambda.py +377 -62
  38. sentry_sdk/integrations/beam.py +176 -0
  39. sentry_sdk/integrations/boto3.py +137 -0
  40. sentry_sdk/integrations/bottle.py +221 -0
  41. sentry_sdk/integrations/celery/__init__.py +529 -0
  42. sentry_sdk/integrations/celery/beat.py +293 -0
  43. sentry_sdk/integrations/celery/utils.py +43 -0
  44. sentry_sdk/integrations/chalice.py +134 -0
  45. sentry_sdk/integrations/clickhouse_driver.py +177 -0
  46. sentry_sdk/integrations/cloud_resource_context.py +280 -0
  47. sentry_sdk/integrations/cohere.py +274 -0
  48. sentry_sdk/integrations/dedupe.py +48 -14
  49. sentry_sdk/integrations/django/__init__.py +584 -191
  50. sentry_sdk/integrations/django/asgi.py +245 -0
  51. sentry_sdk/integrations/django/caching.py +204 -0
  52. sentry_sdk/integrations/django/middleware.py +187 -0
  53. sentry_sdk/integrations/django/signals_handlers.py +91 -0
  54. sentry_sdk/integrations/django/templates.py +79 -5
  55. sentry_sdk/integrations/django/transactions.py +49 -22
  56. sentry_sdk/integrations/django/views.py +96 -0
  57. sentry_sdk/integrations/dramatiq.py +226 -0
  58. sentry_sdk/integrations/excepthook.py +50 -13
  59. sentry_sdk/integrations/executing.py +67 -0
  60. sentry_sdk/integrations/falcon.py +272 -0
  61. sentry_sdk/integrations/fastapi.py +141 -0
  62. sentry_sdk/integrations/flask.py +142 -88
  63. sentry_sdk/integrations/gcp.py +239 -0
  64. sentry_sdk/integrations/gnu_backtrace.py +99 -0
  65. sentry_sdk/integrations/google_genai/__init__.py +301 -0
  66. sentry_sdk/integrations/google_genai/consts.py +16 -0
  67. sentry_sdk/integrations/google_genai/streaming.py +155 -0
  68. sentry_sdk/integrations/google_genai/utils.py +576 -0
  69. sentry_sdk/integrations/gql.py +162 -0
  70. sentry_sdk/integrations/graphene.py +151 -0
  71. sentry_sdk/integrations/grpc/__init__.py +168 -0
  72. sentry_sdk/integrations/grpc/aio/__init__.py +7 -0
  73. sentry_sdk/integrations/grpc/aio/client.py +95 -0
  74. sentry_sdk/integrations/grpc/aio/server.py +100 -0
  75. sentry_sdk/integrations/grpc/client.py +91 -0
  76. sentry_sdk/integrations/grpc/consts.py +1 -0
  77. sentry_sdk/integrations/grpc/server.py +66 -0
  78. sentry_sdk/integrations/httpx.py +178 -0
  79. sentry_sdk/integrations/huey.py +174 -0
  80. sentry_sdk/integrations/huggingface_hub.py +378 -0
  81. sentry_sdk/integrations/langchain.py +1132 -0
  82. sentry_sdk/integrations/langgraph.py +337 -0
  83. sentry_sdk/integrations/launchdarkly.py +61 -0
  84. sentry_sdk/integrations/litellm.py +287 -0
  85. sentry_sdk/integrations/litestar.py +315 -0
  86. sentry_sdk/integrations/logging.py +307 -96
  87. sentry_sdk/integrations/loguru.py +213 -0
  88. sentry_sdk/integrations/mcp.py +566 -0
  89. sentry_sdk/integrations/modules.py +14 -31
  90. sentry_sdk/integrations/openai.py +725 -0
  91. sentry_sdk/integrations/openai_agents/__init__.py +61 -0
  92. sentry_sdk/integrations/openai_agents/consts.py +1 -0
  93. sentry_sdk/integrations/openai_agents/patches/__init__.py +5 -0
  94. sentry_sdk/integrations/openai_agents/patches/agent_run.py +140 -0
  95. sentry_sdk/integrations/openai_agents/patches/error_tracing.py +77 -0
  96. sentry_sdk/integrations/openai_agents/patches/models.py +50 -0
  97. sentry_sdk/integrations/openai_agents/patches/runner.py +45 -0
  98. sentry_sdk/integrations/openai_agents/patches/tools.py +77 -0
  99. sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  100. sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +21 -0
  101. sentry_sdk/integrations/openai_agents/spans/ai_client.py +42 -0
  102. sentry_sdk/integrations/openai_agents/spans/execute_tool.py +48 -0
  103. sentry_sdk/integrations/openai_agents/spans/handoff.py +19 -0
  104. sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +86 -0
  105. sentry_sdk/integrations/openai_agents/utils.py +199 -0
  106. sentry_sdk/integrations/openfeature.py +35 -0
  107. sentry_sdk/integrations/opentelemetry/__init__.py +7 -0
  108. sentry_sdk/integrations/opentelemetry/consts.py +5 -0
  109. sentry_sdk/integrations/opentelemetry/integration.py +58 -0
  110. sentry_sdk/integrations/opentelemetry/propagator.py +117 -0
  111. sentry_sdk/integrations/opentelemetry/span_processor.py +391 -0
  112. sentry_sdk/integrations/otlp.py +82 -0
  113. sentry_sdk/integrations/pure_eval.py +141 -0
  114. sentry_sdk/integrations/pydantic_ai/__init__.py +47 -0
  115. sentry_sdk/integrations/pydantic_ai/consts.py +1 -0
  116. sentry_sdk/integrations/pydantic_ai/patches/__init__.py +4 -0
  117. sentry_sdk/integrations/pydantic_ai/patches/agent_run.py +215 -0
  118. sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py +110 -0
  119. sentry_sdk/integrations/pydantic_ai/patches/model_request.py +40 -0
  120. sentry_sdk/integrations/pydantic_ai/patches/tools.py +98 -0
  121. sentry_sdk/integrations/pydantic_ai/spans/__init__.py +3 -0
  122. sentry_sdk/integrations/pydantic_ai/spans/ai_client.py +246 -0
  123. sentry_sdk/integrations/pydantic_ai/spans/execute_tool.py +49 -0
  124. sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py +112 -0
  125. sentry_sdk/integrations/pydantic_ai/utils.py +223 -0
  126. sentry_sdk/integrations/pymongo.py +214 -0
  127. sentry_sdk/integrations/pyramid.py +112 -68
  128. sentry_sdk/integrations/quart.py +237 -0
  129. sentry_sdk/integrations/ray.py +165 -0
  130. sentry_sdk/integrations/redis/__init__.py +48 -0
  131. sentry_sdk/integrations/redis/_async_common.py +116 -0
  132. sentry_sdk/integrations/redis/_sync_common.py +119 -0
  133. sentry_sdk/integrations/redis/consts.py +19 -0
  134. sentry_sdk/integrations/redis/modules/__init__.py +0 -0
  135. sentry_sdk/integrations/redis/modules/caches.py +118 -0
  136. sentry_sdk/integrations/redis/modules/queries.py +65 -0
  137. sentry_sdk/integrations/redis/rb.py +32 -0
  138. sentry_sdk/integrations/redis/redis.py +69 -0
  139. sentry_sdk/integrations/redis/redis_cluster.py +107 -0
  140. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +50 -0
  141. sentry_sdk/integrations/redis/utils.py +148 -0
  142. sentry_sdk/integrations/rq.py +95 -37
  143. sentry_sdk/integrations/rust_tracing.py +284 -0
  144. sentry_sdk/integrations/sanic.py +294 -123
  145. sentry_sdk/integrations/serverless.py +48 -19
  146. sentry_sdk/integrations/socket.py +96 -0
  147. sentry_sdk/integrations/spark/__init__.py +4 -0
  148. sentry_sdk/integrations/spark/spark_driver.py +316 -0
  149. sentry_sdk/integrations/spark/spark_worker.py +116 -0
  150. sentry_sdk/integrations/sqlalchemy.py +142 -0
  151. sentry_sdk/integrations/starlette.py +737 -0
  152. sentry_sdk/integrations/starlite.py +292 -0
  153. sentry_sdk/integrations/statsig.py +37 -0
  154. sentry_sdk/integrations/stdlib.py +235 -29
  155. sentry_sdk/integrations/strawberry.py +394 -0
  156. sentry_sdk/integrations/sys_exit.py +70 -0
  157. sentry_sdk/integrations/threading.py +158 -28
  158. sentry_sdk/integrations/tornado.py +84 -52
  159. sentry_sdk/integrations/trytond.py +50 -0
  160. sentry_sdk/integrations/typer.py +60 -0
  161. sentry_sdk/integrations/unleash.py +33 -0
  162. sentry_sdk/integrations/unraisablehook.py +53 -0
  163. sentry_sdk/integrations/wsgi.py +201 -119
  164. sentry_sdk/logger.py +96 -0
  165. sentry_sdk/metrics.py +81 -0
  166. sentry_sdk/monitor.py +120 -0
  167. sentry_sdk/profiler/__init__.py +49 -0
  168. sentry_sdk/profiler/continuous_profiler.py +730 -0
  169. sentry_sdk/profiler/transaction_profiler.py +839 -0
  170. sentry_sdk/profiler/utils.py +195 -0
  171. sentry_sdk/py.typed +0 -0
  172. sentry_sdk/scope.py +1713 -85
  173. sentry_sdk/scrubber.py +177 -0
  174. sentry_sdk/serializer.py +405 -0
  175. sentry_sdk/session.py +177 -0
  176. sentry_sdk/sessions.py +275 -0
  177. sentry_sdk/spotlight.py +242 -0
  178. sentry_sdk/tracing.py +1486 -0
  179. sentry_sdk/tracing_utils.py +1236 -0
  180. sentry_sdk/transport.py +806 -134
  181. sentry_sdk/types.py +52 -0
  182. sentry_sdk/utils.py +1625 -465
  183. sentry_sdk/worker.py +54 -25
  184. sentry_sdk-2.46.0.dist-info/METADATA +268 -0
  185. sentry_sdk-2.46.0.dist-info/RECORD +189 -0
  186. {sentry_sdk-0.7.5.dist-info → sentry_sdk-2.46.0.dist-info}/WHEEL +1 -1
  187. sentry_sdk-2.46.0.dist-info/entry_points.txt +2 -0
  188. sentry_sdk-2.46.0.dist-info/licenses/LICENSE +21 -0
  189. sentry_sdk/integrations/celery.py +0 -119
  190. sentry_sdk-0.7.5.dist-info/LICENSE +0 -9
  191. sentry_sdk-0.7.5.dist-info/METADATA +0 -36
  192. sentry_sdk-0.7.5.dist-info/RECORD +0 -39
  193. {sentry_sdk-0.7.5.dist-info → sentry_sdk-2.46.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,144 @@
1
+ import sys
2
+ import functools
3
+
4
+ import sentry_sdk
5
+ from sentry_sdk.consts import OP
6
+ from sentry_sdk.integrations import Integration, DidNotEnable
7
+ from sentry_sdk.utils import event_from_exception, logger, reraise
8
+
9
+ try:
10
+ import asyncio
11
+ from asyncio.tasks import Task
12
+ except ImportError:
13
+ raise DidNotEnable("asyncio not available")
14
+
15
+ from typing import cast, TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from typing import Any, Callable, TypeVar
19
+ from collections.abc import Coroutine
20
+
21
+ from sentry_sdk._types import ExcInfo
22
+
23
+ T = TypeVar("T", bound=Callable[..., Any])
24
+
25
+
26
+ def get_name(coro):
27
+ # type: (Any) -> str
28
+ return (
29
+ getattr(coro, "__qualname__", None)
30
+ or getattr(coro, "__name__", None)
31
+ or "coroutine without __name__"
32
+ )
33
+
34
+
35
+ def _wrap_coroutine(wrapped):
36
+ # type: (Coroutine[Any, Any, Any]) -> Callable[[T], T]
37
+ # Only __name__ and __qualname__ are copied from function to coroutine in CPython
38
+ return functools.partial(
39
+ functools.update_wrapper,
40
+ wrapped=wrapped, # type: ignore
41
+ assigned=("__name__", "__qualname__"),
42
+ updated=(),
43
+ )
44
+
45
+
46
+ def patch_asyncio():
47
+ # type: () -> None
48
+ orig_task_factory = None
49
+ try:
50
+ loop = asyncio.get_running_loop()
51
+ orig_task_factory = loop.get_task_factory()
52
+
53
+ def _sentry_task_factory(loop, coro, **kwargs):
54
+ # type: (asyncio.AbstractEventLoop, Coroutine[Any, Any, Any], Any) -> asyncio.Future[Any]
55
+
56
+ @_wrap_coroutine(coro)
57
+ async def _task_with_sentry_span_creation():
58
+ # type: () -> Any
59
+ result = None
60
+
61
+ with sentry_sdk.isolation_scope():
62
+ with sentry_sdk.start_span(
63
+ op=OP.FUNCTION,
64
+ name=get_name(coro),
65
+ origin=AsyncioIntegration.origin,
66
+ ):
67
+ try:
68
+ result = await coro
69
+ except StopAsyncIteration as e:
70
+ raise e from None
71
+ except Exception:
72
+ reraise(*_capture_exception())
73
+
74
+ return result
75
+
76
+ task = None
77
+
78
+ # Trying to use user set task factory (if there is one)
79
+ if orig_task_factory:
80
+ task = orig_task_factory(
81
+ loop, _task_with_sentry_span_creation(), **kwargs
82
+ )
83
+
84
+ if task is None:
85
+ # The default task factory in `asyncio` does not have its own function
86
+ # but is just a couple of lines in `asyncio.base_events.create_task()`
87
+ # Those lines are copied here.
88
+
89
+ # WARNING:
90
+ # If the default behavior of the task creation in asyncio changes,
91
+ # this will break!
92
+ task = Task(_task_with_sentry_span_creation(), loop=loop, **kwargs)
93
+ if task._source_traceback: # type: ignore
94
+ del task._source_traceback[-1] # type: ignore
95
+
96
+ # Set the task name to include the original coroutine's name
97
+ try:
98
+ cast("asyncio.Task[Any]", task).set_name(
99
+ f"{get_name(coro)} (Sentry-wrapped)"
100
+ )
101
+ except AttributeError:
102
+ # set_name might not be available in all Python versions
103
+ pass
104
+
105
+ return task
106
+
107
+ loop.set_task_factory(_sentry_task_factory) # type: ignore
108
+
109
+ except RuntimeError:
110
+ # When there is no running loop, we have nothing to patch.
111
+ logger.warning(
112
+ "There is no running asyncio loop so there is nothing Sentry can patch. "
113
+ "Please make sure you call sentry_sdk.init() within a running "
114
+ "asyncio loop for the AsyncioIntegration to work. "
115
+ "See https://docs.sentry.io/platforms/python/integrations/asyncio/"
116
+ )
117
+
118
+
119
+ def _capture_exception():
120
+ # type: () -> ExcInfo
121
+ exc_info = sys.exc_info()
122
+
123
+ client = sentry_sdk.get_client()
124
+
125
+ integration = client.get_integration(AsyncioIntegration)
126
+ if integration is not None:
127
+ event, hint = event_from_exception(
128
+ exc_info,
129
+ client_options=client.options,
130
+ mechanism={"type": "asyncio", "handled": False},
131
+ )
132
+ sentry_sdk.capture_event(event, hint=hint)
133
+
134
+ return exc_info
135
+
136
+
137
+ class AsyncioIntegration(Integration):
138
+ identifier = "asyncio"
139
+ origin = f"auto.function.{identifier}"
140
+
141
+ @staticmethod
142
+ def setup_once():
143
+ # type: () -> None
144
+ patch_asyncio()
@@ -0,0 +1,208 @@
1
+ from __future__ import annotations
2
+ import contextlib
3
+ from typing import Any, TypeVar, Callable, Awaitable, Iterator
4
+
5
+ import sentry_sdk
6
+ from sentry_sdk.consts import OP, SPANDATA
7
+ from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable
8
+ from sentry_sdk.tracing import Span
9
+ from sentry_sdk.tracing_utils import add_query_source, record_sql_queries
10
+ from sentry_sdk.utils import (
11
+ ensure_integration_enabled,
12
+ parse_version,
13
+ capture_internal_exceptions,
14
+ )
15
+
16
+ try:
17
+ import asyncpg # type: ignore[import-not-found]
18
+ from asyncpg.cursor import BaseCursor # type: ignore
19
+
20
+ except ImportError:
21
+ raise DidNotEnable("asyncpg not installed.")
22
+
23
+
24
+ class AsyncPGIntegration(Integration):
25
+ identifier = "asyncpg"
26
+ origin = f"auto.db.{identifier}"
27
+ _record_params = False
28
+
29
+ def __init__(self, *, record_params: bool = False):
30
+ AsyncPGIntegration._record_params = record_params
31
+
32
+ @staticmethod
33
+ def setup_once() -> None:
34
+ # asyncpg.__version__ is a string containing the semantic version in the form of "<major>.<minor>.<patch>"
35
+ asyncpg_version = parse_version(asyncpg.__version__)
36
+ _check_minimum_version(AsyncPGIntegration, asyncpg_version)
37
+
38
+ asyncpg.Connection.execute = _wrap_execute(
39
+ asyncpg.Connection.execute,
40
+ )
41
+
42
+ asyncpg.Connection._execute = _wrap_connection_method(
43
+ asyncpg.Connection._execute
44
+ )
45
+ asyncpg.Connection._executemany = _wrap_connection_method(
46
+ asyncpg.Connection._executemany, executemany=True
47
+ )
48
+ asyncpg.Connection.cursor = _wrap_cursor_creation(asyncpg.Connection.cursor)
49
+ asyncpg.Connection.prepare = _wrap_connection_method(asyncpg.Connection.prepare)
50
+ asyncpg.connect_utils._connect_addr = _wrap_connect_addr(
51
+ asyncpg.connect_utils._connect_addr
52
+ )
53
+
54
+
55
+ T = TypeVar("T")
56
+
57
+
58
+ def _wrap_execute(f: Callable[..., Awaitable[T]]) -> Callable[..., Awaitable[T]]:
59
+ async def _inner(*args: Any, **kwargs: Any) -> T:
60
+ if sentry_sdk.get_client().get_integration(AsyncPGIntegration) is None:
61
+ return await f(*args, **kwargs)
62
+
63
+ # Avoid recording calls to _execute twice.
64
+ # Calls to Connection.execute with args also call
65
+ # Connection._execute, which is recorded separately
66
+ # args[0] = the connection object, args[1] is the query
67
+ if len(args) > 2:
68
+ return await f(*args, **kwargs)
69
+
70
+ query = args[1]
71
+ with record_sql_queries(
72
+ cursor=None,
73
+ query=query,
74
+ params_list=None,
75
+ paramstyle=None,
76
+ executemany=False,
77
+ span_origin=AsyncPGIntegration.origin,
78
+ ) as span:
79
+ res = await f(*args, **kwargs)
80
+
81
+ with capture_internal_exceptions():
82
+ add_query_source(span)
83
+
84
+ return res
85
+
86
+ return _inner
87
+
88
+
89
+ SubCursor = TypeVar("SubCursor", bound=BaseCursor)
90
+
91
+
92
+ @contextlib.contextmanager
93
+ def _record(
94
+ cursor: SubCursor | None,
95
+ query: str,
96
+ params_list: tuple[Any, ...] | None,
97
+ *,
98
+ executemany: bool = False,
99
+ ) -> Iterator[Span]:
100
+ integration = sentry_sdk.get_client().get_integration(AsyncPGIntegration)
101
+ if integration is not None and not integration._record_params:
102
+ params_list = None
103
+
104
+ param_style = "pyformat" if params_list else None
105
+
106
+ with record_sql_queries(
107
+ cursor=cursor,
108
+ query=query,
109
+ params_list=params_list,
110
+ paramstyle=param_style,
111
+ executemany=executemany,
112
+ record_cursor_repr=cursor is not None,
113
+ span_origin=AsyncPGIntegration.origin,
114
+ ) as span:
115
+ yield span
116
+
117
+
118
+ def _wrap_connection_method(
119
+ f: Callable[..., Awaitable[T]], *, executemany: bool = False
120
+ ) -> Callable[..., Awaitable[T]]:
121
+ async def _inner(*args: Any, **kwargs: Any) -> T:
122
+ if sentry_sdk.get_client().get_integration(AsyncPGIntegration) is None:
123
+ return await f(*args, **kwargs)
124
+ query = args[1]
125
+ params_list = args[2] if len(args) > 2 else None
126
+ with _record(None, query, params_list, executemany=executemany) as span:
127
+ _set_db_data(span, args[0])
128
+ res = await f(*args, **kwargs)
129
+
130
+ return res
131
+
132
+ return _inner
133
+
134
+
135
+ def _wrap_cursor_creation(f: Callable[..., T]) -> Callable[..., T]:
136
+ @ensure_integration_enabled(AsyncPGIntegration, f)
137
+ def _inner(*args: Any, **kwargs: Any) -> T: # noqa: N807
138
+ query = args[1]
139
+ params_list = args[2] if len(args) > 2 else None
140
+
141
+ with _record(
142
+ None,
143
+ query,
144
+ params_list,
145
+ executemany=False,
146
+ ) as span:
147
+ _set_db_data(span, args[0])
148
+ res = f(*args, **kwargs)
149
+ span.set_data("db.cursor", res)
150
+
151
+ return res
152
+
153
+ return _inner
154
+
155
+
156
+ def _wrap_connect_addr(f: Callable[..., Awaitable[T]]) -> Callable[..., Awaitable[T]]:
157
+ async def _inner(*args: Any, **kwargs: Any) -> T:
158
+ if sentry_sdk.get_client().get_integration(AsyncPGIntegration) is None:
159
+ return await f(*args, **kwargs)
160
+
161
+ user = kwargs["params"].user
162
+ database = kwargs["params"].database
163
+
164
+ with sentry_sdk.start_span(
165
+ op=OP.DB,
166
+ name="connect",
167
+ origin=AsyncPGIntegration.origin,
168
+ ) as span:
169
+ span.set_data(SPANDATA.DB_SYSTEM, "postgresql")
170
+ addr = kwargs.get("addr")
171
+ if addr:
172
+ try:
173
+ span.set_data(SPANDATA.SERVER_ADDRESS, addr[0])
174
+ span.set_data(SPANDATA.SERVER_PORT, addr[1])
175
+ except IndexError:
176
+ pass
177
+ span.set_data(SPANDATA.DB_NAME, database)
178
+ span.set_data(SPANDATA.DB_USER, user)
179
+
180
+ with capture_internal_exceptions():
181
+ sentry_sdk.add_breadcrumb(
182
+ message="connect", category="query", data=span._data
183
+ )
184
+ res = await f(*args, **kwargs)
185
+
186
+ return res
187
+
188
+ return _inner
189
+
190
+
191
+ def _set_db_data(span: Span, conn: Any) -> None:
192
+ span.set_data(SPANDATA.DB_SYSTEM, "postgresql")
193
+
194
+ addr = conn._addr
195
+ if addr:
196
+ try:
197
+ span.set_data(SPANDATA.SERVER_ADDRESS, addr[0])
198
+ span.set_data(SPANDATA.SERVER_PORT, addr[1])
199
+ except IndexError:
200
+ pass
201
+
202
+ database = conn._params.database
203
+ if database:
204
+ span.set_data(SPANDATA.DB_NAME, database)
205
+
206
+ user = conn._params.user
207
+ if user:
208
+ span.set_data(SPANDATA.DB_USER, user)
@@ -1,28 +1,29 @@
1
- from __future__ import absolute_import
2
-
3
1
  import os
4
2
  import sys
5
3
  import atexit
6
4
 
7
- from sentry_sdk.hub import Hub
5
+ import sentry_sdk
8
6
  from sentry_sdk.utils import logger
9
7
  from sentry_sdk.integrations import Integration
8
+ from typing import TYPE_CHECKING
10
9
 
11
- if False:
10
+ if TYPE_CHECKING:
12
11
  from typing import Any
13
12
  from typing import Optional
14
13
 
15
14
 
16
15
  def default_callback(pending, timeout):
16
+ # type: (int, int) -> None
17
17
  """This is the default shutdown callback that is set on the options.
18
18
  It prints out a message to stderr that informs the user that some events
19
19
  are still pending and the process is waiting for them to flush out.
20
20
  """
21
21
 
22
22
  def echo(msg):
23
+ # type: (str) -> None
23
24
  sys.stderr.write(msg + "\n")
24
25
 
25
- echo("Sentry is attempting to send %i pending error messages" % pending)
26
+ echo("Sentry is attempting to send %i pending events" % pending)
26
27
  echo("Waiting up to %s seconds" % timeout)
27
28
  echo("Press Ctrl-%s to quit" % (os.name == "nt" and "Break" or "C"))
28
29
  sys.stderr.flush()
@@ -42,9 +43,15 @@ class AtexitIntegration(Integration):
42
43
  # type: () -> None
43
44
  @atexit.register
44
45
  def _shutdown():
46
+ # type: () -> None
47
+ client = sentry_sdk.get_client()
48
+ integration = client.get_integration(AtexitIntegration)
49
+
50
+ if integration is None:
51
+ return
52
+
45
53
  logger.debug("atexit: got shutdown signal")
46
- hub = Hub.main
47
- integration = hub.get_integration(AtexitIntegration)
48
- if integration is not None:
49
- logger.debug("atexit: shutting down client")
50
- hub.client.close(callback=integration.callback)
54
+ logger.debug("atexit: shutting down client")
55
+ sentry_sdk.get_isolation_scope().end_session()
56
+
57
+ client.close(callback=integration.callback)