sentry-sdk 2.30.0__py2.py3-none-any.whl → 3.0.0a2__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 +3 -8
- sentry_sdk/_compat.py +0 -1
- sentry_sdk/_init_implementation.py +6 -44
- sentry_sdk/_types.py +2 -64
- sentry_sdk/ai/monitoring.py +14 -10
- sentry_sdk/ai/utils.py +1 -1
- sentry_sdk/api.py +56 -169
- sentry_sdk/client.py +27 -72
- sentry_sdk/consts.py +60 -23
- sentry_sdk/debug.py +0 -10
- sentry_sdk/envelope.py +1 -3
- sentry_sdk/feature_flags.py +1 -1
- sentry_sdk/integrations/__init__.py +4 -2
- sentry_sdk/integrations/_asgi_common.py +5 -6
- sentry_sdk/integrations/_wsgi_common.py +11 -40
- sentry_sdk/integrations/aiohttp.py +104 -57
- sentry_sdk/integrations/anthropic.py +10 -7
- sentry_sdk/integrations/arq.py +24 -13
- sentry_sdk/integrations/asgi.py +102 -83
- sentry_sdk/integrations/asyncio.py +1 -0
- sentry_sdk/integrations/asyncpg.py +45 -30
- sentry_sdk/integrations/aws_lambda.py +109 -92
- sentry_sdk/integrations/boto3.py +38 -9
- sentry_sdk/integrations/bottle.py +1 -1
- sentry_sdk/integrations/celery/__init__.py +51 -41
- sentry_sdk/integrations/clickhouse_driver.py +59 -28
- sentry_sdk/integrations/cohere.py +2 -0
- sentry_sdk/integrations/django/__init__.py +25 -46
- sentry_sdk/integrations/django/asgi.py +6 -2
- sentry_sdk/integrations/django/caching.py +13 -22
- sentry_sdk/integrations/django/middleware.py +1 -0
- sentry_sdk/integrations/django/signals_handlers.py +3 -1
- sentry_sdk/integrations/django/templates.py +8 -12
- sentry_sdk/integrations/django/transactions.py +1 -6
- sentry_sdk/integrations/django/views.py +5 -2
- sentry_sdk/integrations/falcon.py +7 -25
- sentry_sdk/integrations/fastapi.py +3 -3
- sentry_sdk/integrations/flask.py +1 -1
- sentry_sdk/integrations/gcp.py +63 -38
- sentry_sdk/integrations/graphene.py +6 -13
- sentry_sdk/integrations/grpc/aio/client.py +14 -8
- sentry_sdk/integrations/grpc/aio/server.py +19 -21
- sentry_sdk/integrations/grpc/client.py +8 -6
- sentry_sdk/integrations/grpc/server.py +12 -14
- sentry_sdk/integrations/httpx.py +47 -12
- sentry_sdk/integrations/huey.py +26 -22
- sentry_sdk/integrations/huggingface_hub.py +1 -0
- sentry_sdk/integrations/langchain.py +22 -15
- sentry_sdk/integrations/litestar.py +4 -2
- sentry_sdk/integrations/logging.py +7 -2
- sentry_sdk/integrations/openai.py +2 -0
- sentry_sdk/integrations/pymongo.py +18 -25
- sentry_sdk/integrations/pyramid.py +1 -1
- sentry_sdk/integrations/quart.py +3 -3
- sentry_sdk/integrations/ray.py +23 -17
- sentry_sdk/integrations/redis/_async_common.py +29 -18
- sentry_sdk/integrations/redis/_sync_common.py +28 -19
- sentry_sdk/integrations/redis/modules/caches.py +13 -10
- sentry_sdk/integrations/redis/modules/queries.py +14 -11
- sentry_sdk/integrations/redis/rb.py +4 -4
- sentry_sdk/integrations/redis/redis.py +6 -6
- sentry_sdk/integrations/redis/redis_cluster.py +18 -18
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +4 -4
- sentry_sdk/integrations/redis/utils.py +64 -24
- sentry_sdk/integrations/rq.py +68 -23
- sentry_sdk/integrations/rust_tracing.py +28 -43
- sentry_sdk/integrations/sanic.py +23 -13
- sentry_sdk/integrations/socket.py +9 -5
- sentry_sdk/integrations/sqlalchemy.py +8 -8
- sentry_sdk/integrations/starlette.py +11 -31
- sentry_sdk/integrations/starlite.py +4 -2
- sentry_sdk/integrations/stdlib.py +56 -9
- sentry_sdk/integrations/strawberry.py +40 -59
- sentry_sdk/integrations/threading.py +10 -26
- sentry_sdk/integrations/tornado.py +57 -18
- sentry_sdk/integrations/trytond.py +4 -1
- sentry_sdk/integrations/wsgi.py +84 -38
- sentry_sdk/opentelemetry/__init__.py +9 -0
- sentry_sdk/opentelemetry/consts.py +33 -0
- sentry_sdk/opentelemetry/contextvars_context.py +81 -0
- sentry_sdk/{integrations/opentelemetry → opentelemetry}/propagator.py +19 -28
- sentry_sdk/opentelemetry/sampler.py +326 -0
- sentry_sdk/opentelemetry/scope.py +218 -0
- sentry_sdk/opentelemetry/span_processor.py +335 -0
- sentry_sdk/opentelemetry/tracing.py +59 -0
- sentry_sdk/opentelemetry/utils.py +484 -0
- sentry_sdk/profiler/__init__.py +0 -40
- sentry_sdk/profiler/continuous_profiler.py +1 -30
- sentry_sdk/profiler/transaction_profiler.py +5 -56
- sentry_sdk/scope.py +108 -361
- sentry_sdk/sessions.py +0 -87
- sentry_sdk/tracing.py +415 -1161
- sentry_sdk/tracing_utils.py +130 -166
- sentry_sdk/transport.py +4 -104
- sentry_sdk/utils.py +169 -152
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/METADATA +3 -5
- sentry_sdk-3.0.0a2.dist-info/RECORD +154 -0
- sentry_sdk-3.0.0a2.dist-info/entry_points.txt +2 -0
- sentry_sdk/hub.py +0 -739
- sentry_sdk/integrations/opentelemetry/__init__.py +0 -7
- sentry_sdk/integrations/opentelemetry/consts.py +0 -5
- sentry_sdk/integrations/opentelemetry/integration.py +0 -58
- sentry_sdk/integrations/opentelemetry/span_processor.py +0 -391
- sentry_sdk/metrics.py +0 -965
- sentry_sdk-2.30.0.dist-info/RECORD +0 -152
- sentry_sdk-2.30.0.dist-info/entry_points.txt +0 -2
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/WHEEL +0 -0
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/top_level.txt +0 -0
sentry_sdk/integrations/httpx.py
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import sentry_sdk
|
|
2
|
-
from sentry_sdk.consts import OP, SPANDATA
|
|
2
|
+
from sentry_sdk.consts import OP, SPANDATA, BAGGAGE_HEADER_NAME
|
|
3
3
|
from sentry_sdk.integrations import Integration, DidNotEnable
|
|
4
|
-
from sentry_sdk.tracing import BAGGAGE_HEADER_NAME
|
|
5
4
|
from sentry_sdk.tracing_utils import Baggage, should_propagate_trace
|
|
6
5
|
from sentry_sdk.utils import (
|
|
7
6
|
SENSITIVE_DATA_SUBSTITUTE,
|
|
8
7
|
capture_internal_exceptions,
|
|
9
8
|
ensure_integration_enabled,
|
|
9
|
+
http_client_status_to_breadcrumb_level,
|
|
10
10
|
logger,
|
|
11
11
|
parse_url,
|
|
12
|
+
set_thread_info_from_span,
|
|
12
13
|
)
|
|
13
14
|
|
|
14
15
|
from typing import TYPE_CHECKING
|
|
@@ -60,12 +61,20 @@ def _install_httpx_client():
|
|
|
60
61
|
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
|
|
61
62
|
),
|
|
62
63
|
origin=HttpxIntegration.origin,
|
|
64
|
+
only_if_parent=True,
|
|
63
65
|
) as span:
|
|
64
|
-
|
|
66
|
+
data = {
|
|
67
|
+
SPANDATA.HTTP_METHOD: request.method,
|
|
68
|
+
}
|
|
69
|
+
set_thread_info_from_span(data, span)
|
|
70
|
+
|
|
65
71
|
if parsed_url is not None:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
data["url"] = parsed_url.url
|
|
73
|
+
data[SPANDATA.HTTP_QUERY] = parsed_url.query
|
|
74
|
+
data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment
|
|
75
|
+
|
|
76
|
+
for key, value in data.items():
|
|
77
|
+
span.set_attribute(key, value)
|
|
69
78
|
|
|
70
79
|
if should_propagate_trace(sentry_sdk.get_client(), str(request.url)):
|
|
71
80
|
for (
|
|
@@ -86,7 +95,17 @@ def _install_httpx_client():
|
|
|
86
95
|
rv = real_send(self, request, **kwargs)
|
|
87
96
|
|
|
88
97
|
span.set_http_status(rv.status_code)
|
|
89
|
-
span.
|
|
98
|
+
span.set_attribute("reason", rv.reason_phrase)
|
|
99
|
+
|
|
100
|
+
data[SPANDATA.HTTP_STATUS_CODE] = rv.status_code
|
|
101
|
+
data["reason"] = rv.reason_phrase
|
|
102
|
+
|
|
103
|
+
sentry_sdk.add_breadcrumb(
|
|
104
|
+
type="http",
|
|
105
|
+
category="httplib",
|
|
106
|
+
data=data,
|
|
107
|
+
level=http_client_status_to_breadcrumb_level(rv.status_code),
|
|
108
|
+
)
|
|
90
109
|
|
|
91
110
|
return rv
|
|
92
111
|
|
|
@@ -114,12 +133,18 @@ def _install_httpx_async_client():
|
|
|
114
133
|
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
|
|
115
134
|
),
|
|
116
135
|
origin=HttpxIntegration.origin,
|
|
136
|
+
only_if_parent=True,
|
|
117
137
|
) as span:
|
|
118
|
-
|
|
138
|
+
data = {
|
|
139
|
+
SPANDATA.HTTP_METHOD: request.method,
|
|
140
|
+
}
|
|
119
141
|
if parsed_url is not None:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
142
|
+
data["url"] = parsed_url.url
|
|
143
|
+
data[SPANDATA.HTTP_QUERY] = parsed_url.query
|
|
144
|
+
data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment
|
|
145
|
+
|
|
146
|
+
for key, value in data.items():
|
|
147
|
+
span.set_attribute(key, value)
|
|
123
148
|
|
|
124
149
|
if should_propagate_trace(sentry_sdk.get_client(), str(request.url)):
|
|
125
150
|
for (
|
|
@@ -142,7 +167,17 @@ def _install_httpx_async_client():
|
|
|
142
167
|
rv = await real_send(self, request, **kwargs)
|
|
143
168
|
|
|
144
169
|
span.set_http_status(rv.status_code)
|
|
145
|
-
span.
|
|
170
|
+
span.set_attribute("reason", rv.reason_phrase)
|
|
171
|
+
|
|
172
|
+
data[SPANDATA.HTTP_STATUS_CODE] = rv.status_code
|
|
173
|
+
data["reason"] = rv.reason_phrase
|
|
174
|
+
|
|
175
|
+
sentry_sdk.add_breadcrumb(
|
|
176
|
+
type="http",
|
|
177
|
+
category="httplib",
|
|
178
|
+
data=data,
|
|
179
|
+
level=http_client_status_to_breadcrumb_level(rv.status_code),
|
|
180
|
+
)
|
|
146
181
|
|
|
147
182
|
return rv
|
|
148
183
|
|
sentry_sdk/integrations/huey.py
CHANGED
|
@@ -2,15 +2,16 @@ import sys
|
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
|
|
4
4
|
import sentry_sdk
|
|
5
|
-
from sentry_sdk.api import
|
|
6
|
-
from sentry_sdk.consts import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from sentry_sdk.tracing import (
|
|
5
|
+
from sentry_sdk.api import get_baggage, get_traceparent
|
|
6
|
+
from sentry_sdk.consts import (
|
|
7
|
+
OP,
|
|
8
|
+
SPANSTATUS,
|
|
10
9
|
BAGGAGE_HEADER_NAME,
|
|
11
10
|
SENTRY_TRACE_HEADER_NAME,
|
|
12
11
|
TransactionSource,
|
|
13
12
|
)
|
|
13
|
+
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
14
|
+
from sentry_sdk.scope import should_send_default_pii
|
|
14
15
|
from sentry_sdk.utils import (
|
|
15
16
|
capture_internal_exceptions,
|
|
16
17
|
ensure_integration_enabled,
|
|
@@ -61,6 +62,7 @@ def patch_enqueue():
|
|
|
61
62
|
op=OP.QUEUE_SUBMIT_HUEY,
|
|
62
63
|
name=task.name,
|
|
63
64
|
origin=HueyIntegration.origin,
|
|
65
|
+
only_if_parent=True,
|
|
64
66
|
):
|
|
65
67
|
if not isinstance(task, PeriodicTask):
|
|
66
68
|
# Attach trace propagation data to task kwargs. We do
|
|
@@ -109,11 +111,13 @@ def _capture_exception(exc_info):
|
|
|
109
111
|
# type: (ExcInfo) -> None
|
|
110
112
|
scope = sentry_sdk.get_current_scope()
|
|
111
113
|
|
|
112
|
-
if
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
if scope.root_span is not None:
|
|
115
|
+
if exc_info[0] in HUEY_CONTROL_FLOW_EXCEPTIONS:
|
|
116
|
+
scope.root_span.set_status(SPANSTATUS.ABORTED)
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
scope.root_span.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
115
120
|
|
|
116
|
-
scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
117
121
|
event, hint = event_from_exception(
|
|
118
122
|
exc_info,
|
|
119
123
|
client_options=sentry_sdk.get_client().options,
|
|
@@ -135,6 +139,10 @@ def _wrap_task_execute(func):
|
|
|
135
139
|
_capture_exception(exc_info)
|
|
136
140
|
reraise(*exc_info)
|
|
137
141
|
|
|
142
|
+
root_span = sentry_sdk.get_current_scope().root_span
|
|
143
|
+
if root_span is not None:
|
|
144
|
+
root_span.set_status(SPANSTATUS.OK)
|
|
145
|
+
|
|
138
146
|
return result
|
|
139
147
|
|
|
140
148
|
return _sentry_execute # type: ignore
|
|
@@ -153,22 +161,18 @@ def patch_execute():
|
|
|
153
161
|
scope.clear_breadcrumbs()
|
|
154
162
|
scope.add_event_processor(_make_event_processor(task))
|
|
155
163
|
|
|
156
|
-
sentry_headers = task.kwargs.pop("sentry_headers", None)
|
|
157
|
-
|
|
158
|
-
transaction = continue_trace(
|
|
159
|
-
sentry_headers or {},
|
|
160
|
-
name=task.name,
|
|
161
|
-
op=OP.QUEUE_TASK_HUEY,
|
|
162
|
-
source=TransactionSource.TASK,
|
|
163
|
-
origin=HueyIntegration.origin,
|
|
164
|
-
)
|
|
165
|
-
transaction.set_status(SPANSTATUS.OK)
|
|
166
|
-
|
|
167
164
|
if not getattr(task, "_sentry_is_patched", False):
|
|
168
165
|
task.execute = _wrap_task_execute(task.execute)
|
|
169
166
|
task._sentry_is_patched = True
|
|
170
167
|
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
sentry_headers = task.kwargs.pop("sentry_headers", {})
|
|
169
|
+
with sentry_sdk.continue_trace(sentry_headers):
|
|
170
|
+
with sentry_sdk.start_span(
|
|
171
|
+
name=task.name,
|
|
172
|
+
op=OP.QUEUE_TASK_HUEY,
|
|
173
|
+
source=TransactionSource.TASK,
|
|
174
|
+
origin=HueyIntegration.origin,
|
|
175
|
+
):
|
|
176
|
+
return old_execute(self, task, timestamp)
|
|
173
177
|
|
|
174
178
|
Huey._execute = _sentry_execute
|
|
@@ -3,7 +3,7 @@ from functools import wraps
|
|
|
3
3
|
|
|
4
4
|
import sentry_sdk
|
|
5
5
|
from sentry_sdk.ai.monitoring import set_ai_pipeline_name, record_token_usage
|
|
6
|
-
from sentry_sdk.consts import OP, SPANDATA
|
|
6
|
+
from sentry_sdk.consts import OP, SPANDATA, SPANSTATUS
|
|
7
7
|
from sentry_sdk.ai.utils import set_data_normalized
|
|
8
8
|
from sentry_sdk.scope import should_send_default_pii
|
|
9
9
|
from sentry_sdk.tracing import Span
|
|
@@ -72,7 +72,6 @@ class LangchainIntegration(Integration):
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
class WatchedSpan:
|
|
75
|
-
span = None # type: Span
|
|
76
75
|
num_completion_tokens = 0 # type: int
|
|
77
76
|
num_prompt_tokens = 0 # type: int
|
|
78
77
|
no_collect_tokens = False # type: bool
|
|
@@ -123,8 +122,9 @@ class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
|
|
|
123
122
|
span_data = self.span_map[run_id]
|
|
124
123
|
if not span_data:
|
|
125
124
|
return
|
|
126
|
-
sentry_sdk.capture_exception(error
|
|
127
|
-
span_data.span.
|
|
125
|
+
sentry_sdk.capture_exception(error)
|
|
126
|
+
span_data.span.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
127
|
+
span_data.span.finish()
|
|
128
128
|
del self.span_map[run_id]
|
|
129
129
|
|
|
130
130
|
def _normalize_langchain_message(self, message):
|
|
@@ -136,21 +136,27 @@ class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
|
|
|
136
136
|
def _create_span(self, run_id, parent_id, **kwargs):
|
|
137
137
|
# type: (SentryLangchainCallback, UUID, Optional[Any], Any) -> WatchedSpan
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
parent_span
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
139
|
+
parent_watched_span = self.span_map.get(parent_id) if parent_id else None
|
|
140
|
+
sentry_span = sentry_sdk.start_span(
|
|
141
|
+
parent_span=parent_watched_span.span if parent_watched_span else None,
|
|
142
|
+
only_if_parent=True,
|
|
143
|
+
**kwargs,
|
|
144
|
+
)
|
|
145
|
+
watched_span = WatchedSpan(sentry_span)
|
|
146
|
+
if parent_watched_span:
|
|
147
|
+
parent_watched_span.children.append(watched_span)
|
|
147
148
|
|
|
148
149
|
if kwargs.get("op", "").startswith("ai.pipeline."):
|
|
149
150
|
if kwargs.get("name"):
|
|
150
151
|
set_ai_pipeline_name(kwargs.get("name"))
|
|
151
152
|
watched_span.is_pipeline = True
|
|
152
153
|
|
|
153
|
-
|
|
154
|
+
# the same run_id is reused for the pipeline it seems
|
|
155
|
+
# so we need to end the older span to avoid orphan spans
|
|
156
|
+
existing_span_data = self.span_map.get(run_id)
|
|
157
|
+
if existing_span_data is not None:
|
|
158
|
+
self._exit_span(existing_span_data, run_id)
|
|
159
|
+
|
|
154
160
|
self.span_map[run_id] = watched_span
|
|
155
161
|
self.gc_span_map()
|
|
156
162
|
return watched_span
|
|
@@ -161,7 +167,8 @@ class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
|
|
|
161
167
|
if span_data.is_pipeline:
|
|
162
168
|
set_ai_pipeline_name(None)
|
|
163
169
|
|
|
164
|
-
span_data.span.
|
|
170
|
+
span_data.span.set_status(SPANSTATUS.OK)
|
|
171
|
+
span_data.span.finish()
|
|
165
172
|
del self.span_map[run_id]
|
|
166
173
|
|
|
167
174
|
def on_llm_start(
|
|
@@ -222,7 +229,7 @@ class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
|
|
|
222
229
|
if not model and "anthropic" in all_params.get("_type"):
|
|
223
230
|
model = "claude-2"
|
|
224
231
|
if model:
|
|
225
|
-
span.
|
|
232
|
+
span.set_attribute(SPANDATA.AI_MODEL_ID, model)
|
|
226
233
|
if should_send_default_pii() and self.include_prompts:
|
|
227
234
|
set_data_normalized(
|
|
228
235
|
span,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from collections.abc import Set
|
|
2
2
|
import sentry_sdk
|
|
3
|
-
from sentry_sdk.consts import OP
|
|
3
|
+
from sentry_sdk.consts import OP, TransactionSource, SOURCE_FOR_STYLE
|
|
4
4
|
from sentry_sdk.integrations import (
|
|
5
5
|
_DEFAULT_FAILED_REQUEST_STATUS_CODES,
|
|
6
6
|
DidNotEnable,
|
|
@@ -9,7 +9,6 @@ from sentry_sdk.integrations import (
|
|
|
9
9
|
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
|
|
10
10
|
from sentry_sdk.integrations.logging import ignore_logger
|
|
11
11
|
from sentry_sdk.scope import should_send_default_pii
|
|
12
|
-
from sentry_sdk.tracing import TransactionSource, SOURCE_FOR_STYLE
|
|
13
12
|
from sentry_sdk.utils import (
|
|
14
13
|
ensure_integration_enabled,
|
|
15
14
|
event_from_exception,
|
|
@@ -153,6 +152,7 @@ def enable_span_for_middleware(middleware):
|
|
|
153
152
|
op=OP.MIDDLEWARE_LITESTAR,
|
|
154
153
|
name=middleware_name,
|
|
155
154
|
origin=LitestarIntegration.origin,
|
|
155
|
+
only_if_parent=True,
|
|
156
156
|
) as middleware_span:
|
|
157
157
|
middleware_span.set_tag("litestar.middleware_name", middleware_name)
|
|
158
158
|
|
|
@@ -165,6 +165,7 @@ def enable_span_for_middleware(middleware):
|
|
|
165
165
|
op=OP.MIDDLEWARE_LITESTAR_RECEIVE,
|
|
166
166
|
name=getattr(receive, "__qualname__", str(receive)),
|
|
167
167
|
origin=LitestarIntegration.origin,
|
|
168
|
+
only_if_parent=True,
|
|
168
169
|
) as span:
|
|
169
170
|
span.set_tag("litestar.middleware_name", middleware_name)
|
|
170
171
|
return await receive(*args, **kwargs)
|
|
@@ -182,6 +183,7 @@ def enable_span_for_middleware(middleware):
|
|
|
182
183
|
op=OP.MIDDLEWARE_LITESTAR_SEND,
|
|
183
184
|
name=getattr(send, "__qualname__", str(send)),
|
|
184
185
|
origin=LitestarIntegration.origin,
|
|
186
|
+
only_if_parent=True,
|
|
185
187
|
) as span:
|
|
186
188
|
span.set_tag("litestar.middleware_name", middleware_name)
|
|
187
189
|
return await send(message)
|
|
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|
|
25
25
|
from typing import Optional
|
|
26
26
|
|
|
27
27
|
DEFAULT_LEVEL = logging.INFO
|
|
28
|
-
DEFAULT_EVENT_LEVEL =
|
|
28
|
+
DEFAULT_EVENT_LEVEL = None # None means no events are captured
|
|
29
29
|
LOGGING_TO_EVENT_LEVEL = {
|
|
30
30
|
logging.NOTSET: "notset",
|
|
31
31
|
logging.DEBUG: "debug",
|
|
@@ -54,7 +54,12 @@ SEVERITY_TO_OTEL_SEVERITY = {
|
|
|
54
54
|
# Note: Ignoring by logger name here is better than mucking with thread-locals.
|
|
55
55
|
# We do not necessarily know whether thread-locals work 100% correctly in the user's environment.
|
|
56
56
|
_IGNORED_LOGGERS = set(
|
|
57
|
-
[
|
|
57
|
+
[
|
|
58
|
+
"sentry_sdk.errors",
|
|
59
|
+
"urllib3.connectionpool",
|
|
60
|
+
"urllib3.connection",
|
|
61
|
+
"opentelemetry.*",
|
|
62
|
+
]
|
|
58
63
|
)
|
|
59
64
|
|
|
60
65
|
|
|
@@ -139,6 +139,7 @@ def _new_chat_completion_common(f, *args, **kwargs):
|
|
|
139
139
|
op=consts.OP.OPENAI_CHAT_COMPLETIONS_CREATE,
|
|
140
140
|
name="Chat Completion",
|
|
141
141
|
origin=OpenAIIntegration.origin,
|
|
142
|
+
only_if_parent=True,
|
|
142
143
|
)
|
|
143
144
|
span.__enter__()
|
|
144
145
|
|
|
@@ -324,6 +325,7 @@ def _new_embeddings_create_common(f, *args, **kwargs):
|
|
|
324
325
|
op=consts.OP.OPENAI_EMBEDDINGS_CREATE,
|
|
325
326
|
description="OpenAI Embedding Creation",
|
|
326
327
|
origin=OpenAIIntegration.origin,
|
|
328
|
+
only_if_parent=True,
|
|
327
329
|
) as span:
|
|
328
330
|
if "input" in kwargs and (
|
|
329
331
|
should_send_default_pii() and integration.include_prompts
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import copy
|
|
2
|
-
import json
|
|
3
2
|
|
|
4
3
|
import sentry_sdk
|
|
5
4
|
from sentry_sdk.consts import SPANSTATUS, SPANDATA, OP
|
|
6
5
|
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
7
6
|
from sentry_sdk.scope import should_send_default_pii
|
|
8
7
|
from sentry_sdk.tracing import Span
|
|
9
|
-
from sentry_sdk.utils import capture_internal_exceptions
|
|
8
|
+
from sentry_sdk.utils import capture_internal_exceptions, _serialize_span_attribute
|
|
10
9
|
|
|
11
10
|
try:
|
|
12
11
|
from pymongo import monitoring
|
|
@@ -127,56 +126,50 @@ class CommandTracer(monitoring.CommandListener):
|
|
|
127
126
|
command.pop("$clusterTime", None)
|
|
128
127
|
command.pop("$signature", None)
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
data = {
|
|
130
|
+
SPANDATA.DB_NAME: event.database_name,
|
|
132
131
|
SPANDATA.DB_SYSTEM: "mongodb",
|
|
133
132
|
SPANDATA.DB_OPERATION: event.command_name,
|
|
134
133
|
SPANDATA.DB_MONGODB_COLLECTION: command.get(event.command_name),
|
|
135
134
|
}
|
|
136
135
|
|
|
137
136
|
try:
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
data["net.peer.name"] = event.connection_id[0]
|
|
138
|
+
data["net.peer.port"] = str(event.connection_id[1])
|
|
140
139
|
except TypeError:
|
|
141
140
|
pass
|
|
142
141
|
|
|
143
|
-
data = {"operation_ids": {}} # type: Dict[str, Any]
|
|
144
|
-
data["operation_ids"]["operation"] = event.operation_id
|
|
145
|
-
data["operation_ids"]["request"] = event.request_id
|
|
146
|
-
|
|
147
|
-
data.update(_get_db_data(event))
|
|
148
|
-
|
|
149
142
|
try:
|
|
150
143
|
lsid = command.pop("lsid")["id"]
|
|
151
|
-
data["
|
|
144
|
+
data["session_id"] = str(lsid)
|
|
152
145
|
except KeyError:
|
|
153
146
|
pass
|
|
154
147
|
|
|
155
148
|
if not should_send_default_pii():
|
|
156
149
|
command = _strip_pii(command)
|
|
157
150
|
|
|
158
|
-
query =
|
|
151
|
+
query = _serialize_span_attribute(command)
|
|
159
152
|
span = sentry_sdk.start_span(
|
|
160
153
|
op=OP.DB,
|
|
161
154
|
name=query,
|
|
162
155
|
origin=PyMongoIntegration.origin,
|
|
156
|
+
only_if_parent=True,
|
|
163
157
|
)
|
|
164
158
|
|
|
165
|
-
for tag, value in tags.items():
|
|
166
|
-
# set the tag for backwards-compatibility.
|
|
167
|
-
# TODO: remove the set_tag call in the next major release!
|
|
168
|
-
span.set_tag(tag, value)
|
|
169
|
-
|
|
170
|
-
span.set_data(tag, value)
|
|
171
|
-
|
|
172
|
-
for key, value in data.items():
|
|
173
|
-
span.set_data(key, value)
|
|
174
|
-
|
|
175
159
|
with capture_internal_exceptions():
|
|
176
160
|
sentry_sdk.add_breadcrumb(
|
|
177
|
-
message=query, category="query", type=OP.DB, data=
|
|
161
|
+
message=query, category="query", type=OP.DB, data=data
|
|
178
162
|
)
|
|
179
163
|
|
|
164
|
+
for key, value in data.items():
|
|
165
|
+
span.set_attribute(key, value)
|
|
166
|
+
|
|
167
|
+
for key, value in _get_db_data(event).items():
|
|
168
|
+
span.set_attribute(key, value)
|
|
169
|
+
|
|
170
|
+
span.set_attribute("operation_id", event.operation_id)
|
|
171
|
+
span.set_attribute("request_id", event.request_id)
|
|
172
|
+
|
|
180
173
|
self._ongoing_operations[self._operation_key(event)] = span.__enter__()
|
|
181
174
|
|
|
182
175
|
def failed(self, event):
|
|
@@ -4,11 +4,11 @@ import sys
|
|
|
4
4
|
import weakref
|
|
5
5
|
|
|
6
6
|
import sentry_sdk
|
|
7
|
+
from sentry_sdk.consts import SOURCE_FOR_STYLE
|
|
7
8
|
from sentry_sdk.integrations import Integration, DidNotEnable
|
|
8
9
|
from sentry_sdk.integrations._wsgi_common import RequestExtractor
|
|
9
10
|
from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
|
|
10
11
|
from sentry_sdk.scope import should_send_default_pii
|
|
11
|
-
from sentry_sdk.tracing import SOURCE_FOR_STYLE
|
|
12
12
|
from sentry_sdk.utils import (
|
|
13
13
|
capture_internal_exceptions,
|
|
14
14
|
ensure_integration_enabled,
|
sentry_sdk/integrations/quart.py
CHANGED
|
@@ -3,11 +3,11 @@ import inspect
|
|
|
3
3
|
from functools import wraps
|
|
4
4
|
|
|
5
5
|
import sentry_sdk
|
|
6
|
+
from sentry_sdk.consts import SOURCE_FOR_STYLE
|
|
6
7
|
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
7
8
|
from sentry_sdk.integrations._wsgi_common import _filter_headers
|
|
8
9
|
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
|
|
9
10
|
from sentry_sdk.scope import should_send_default_pii
|
|
10
|
-
from sentry_sdk.tracing import SOURCE_FOR_STYLE
|
|
11
11
|
from sentry_sdk.utils import (
|
|
12
12
|
capture_internal_exceptions,
|
|
13
13
|
ensure_integration_enabled,
|
|
@@ -122,8 +122,8 @@ def patch_scaffold_route():
|
|
|
122
122
|
def _sentry_func(*args, **kwargs):
|
|
123
123
|
# type: (*Any, **Any) -> Any
|
|
124
124
|
current_scope = sentry_sdk.get_current_scope()
|
|
125
|
-
if current_scope.
|
|
126
|
-
current_scope.
|
|
125
|
+
if current_scope.root_span is not None:
|
|
126
|
+
current_scope.root_span.update_active_thread()
|
|
127
127
|
|
|
128
128
|
sentry_scope = sentry_sdk.get_isolation_scope()
|
|
129
129
|
if sentry_scope.profile is not None:
|
sentry_sdk/integrations/ray.py
CHANGED
|
@@ -26,6 +26,8 @@ if TYPE_CHECKING:
|
|
|
26
26
|
from typing import Any, Optional
|
|
27
27
|
from sentry_sdk.utils import ExcInfo
|
|
28
28
|
|
|
29
|
+
DEFAULT_TRANSACTION_NAME = "unknown Ray function"
|
|
30
|
+
|
|
29
31
|
|
|
30
32
|
def _check_sentry_initialized():
|
|
31
33
|
# type: () -> None
|
|
@@ -58,25 +60,28 @@ def _patch_ray_remote():
|
|
|
58
60
|
"""
|
|
59
61
|
_check_sentry_initialized()
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
name=qualname_from_function(f),
|
|
65
|
-
origin=RayIntegration.origin,
|
|
63
|
+
root_span_name = qualname_from_function(f) or DEFAULT_TRANSACTION_NAME
|
|
64
|
+
sentry_sdk.get_current_scope().set_transaction_name(
|
|
65
|
+
root_span_name,
|
|
66
66
|
source=TransactionSource.TASK,
|
|
67
67
|
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
with sentry_sdk.continue_trace(_tracing or {}):
|
|
69
|
+
with sentry_sdk.start_span(
|
|
70
|
+
op=OP.QUEUE_TASK_RAY,
|
|
71
|
+
name=root_span_name,
|
|
72
|
+
origin=RayIntegration.origin,
|
|
73
|
+
source=TransactionSource.TASK,
|
|
74
|
+
) as root_span:
|
|
75
|
+
try:
|
|
76
|
+
result = f(*f_args, **f_kwargs)
|
|
77
|
+
root_span.set_status(SPANSTATUS.OK)
|
|
78
|
+
except Exception:
|
|
79
|
+
root_span.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
80
|
+
exc_info = sys.exc_info()
|
|
81
|
+
_capture_exception(exc_info)
|
|
82
|
+
reraise(*exc_info)
|
|
83
|
+
|
|
84
|
+
return result
|
|
80
85
|
|
|
81
86
|
rv = old_remote(_f, *args, *kwargs)
|
|
82
87
|
old_remote_method = rv.remote
|
|
@@ -90,6 +95,7 @@ def _patch_ray_remote():
|
|
|
90
95
|
op=OP.QUEUE_SUBMIT_RAY,
|
|
91
96
|
name=qualname_from_function(f),
|
|
92
97
|
origin=RayIntegration.origin,
|
|
98
|
+
only_if_parent=True,
|
|
93
99
|
) as span:
|
|
94
100
|
tracing = {
|
|
95
101
|
k: v
|
|
@@ -3,14 +3,15 @@ from sentry_sdk.consts import OP
|
|
|
3
3
|
from sentry_sdk.integrations.redis.consts import SPAN_ORIGIN
|
|
4
4
|
from sentry_sdk.integrations.redis.modules.caches import (
|
|
5
5
|
_compile_cache_span_properties,
|
|
6
|
-
|
|
6
|
+
_get_cache_data,
|
|
7
7
|
)
|
|
8
8
|
from sentry_sdk.integrations.redis.modules.queries import _compile_db_span_properties
|
|
9
9
|
from sentry_sdk.integrations.redis.utils import (
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
_create_breadcrumb,
|
|
11
|
+
_get_client_data,
|
|
12
|
+
_get_pipeline_data,
|
|
13
|
+
_update_span,
|
|
12
14
|
)
|
|
13
|
-
from sentry_sdk.tracing import Span
|
|
14
15
|
from sentry_sdk.utils import capture_internal_exceptions
|
|
15
16
|
|
|
16
17
|
from typing import TYPE_CHECKING
|
|
@@ -23,9 +24,9 @@ if TYPE_CHECKING:
|
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def patch_redis_async_pipeline(
|
|
26
|
-
pipeline_cls, is_cluster, get_command_args_fn,
|
|
27
|
+
pipeline_cls, is_cluster, get_command_args_fn, get_db_data_fn
|
|
27
28
|
):
|
|
28
|
-
# type: (Union[type[Pipeline[Any]], type[ClusterPipeline[Any]]], bool, Any, Callable[[
|
|
29
|
+
# type: (Union[type[Pipeline[Any]], type[ClusterPipeline[Any]]], bool, Any, Callable[[Any], dict[str, Any]]) -> None
|
|
29
30
|
old_execute = pipeline_cls.execute
|
|
30
31
|
|
|
31
32
|
from sentry_sdk.integrations.redis import RedisIntegration
|
|
@@ -39,8 +40,11 @@ def patch_redis_async_pipeline(
|
|
|
39
40
|
op=OP.DB_REDIS,
|
|
40
41
|
name="redis.pipeline.execute",
|
|
41
42
|
origin=SPAN_ORIGIN,
|
|
43
|
+
only_if_parent=True,
|
|
42
44
|
) as span:
|
|
43
45
|
with capture_internal_exceptions():
|
|
46
|
+
span_data = get_db_data_fn(self)
|
|
47
|
+
|
|
44
48
|
try:
|
|
45
49
|
command_seq = self._execution_strategy._command_queue
|
|
46
50
|
except AttributeError:
|
|
@@ -49,22 +53,22 @@ def patch_redis_async_pipeline(
|
|
|
49
53
|
else:
|
|
50
54
|
command_seq = self.command_stack
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
is_cluster,
|
|
56
|
-
|
|
57
|
-
False if is_cluster else self.is_transaction,
|
|
58
|
-
command_seq,
|
|
56
|
+
pipeline_data = _get_pipeline_data(
|
|
57
|
+
is_cluster=is_cluster,
|
|
58
|
+
get_command_args_fn=get_command_args_fn,
|
|
59
|
+
is_transaction=False if is_cluster else self.is_transaction,
|
|
60
|
+
command_seq=command_seq,
|
|
59
61
|
)
|
|
62
|
+
_update_span(span, span_data, pipeline_data)
|
|
63
|
+
_create_breadcrumb("redis.pipeline.execute", span_data, pipeline_data)
|
|
60
64
|
|
|
61
65
|
return await old_execute(self, *args, **kwargs)
|
|
62
66
|
|
|
63
67
|
pipeline_cls.execute = _sentry_execute # type: ignore
|
|
64
68
|
|
|
65
69
|
|
|
66
|
-
def patch_redis_async_client(cls, is_cluster,
|
|
67
|
-
# type: (Union[type[StrictRedis[Any]], type[RedisCluster[Any]]], bool, Callable[[
|
|
70
|
+
def patch_redis_async_client(cls, is_cluster, get_db_data_fn):
|
|
71
|
+
# type: (Union[type[StrictRedis[Any]], type[RedisCluster[Any]]], bool, Callable[[Any], dict[str, Any]]) -> None
|
|
68
72
|
old_execute_command = cls.execute_command
|
|
69
73
|
|
|
70
74
|
from sentry_sdk.integrations.redis import RedisIntegration
|
|
@@ -88,6 +92,7 @@ def patch_redis_async_client(cls, is_cluster, set_db_data_fn):
|
|
|
88
92
|
op=cache_properties["op"],
|
|
89
93
|
name=cache_properties["description"],
|
|
90
94
|
origin=SPAN_ORIGIN,
|
|
95
|
+
only_if_parent=True,
|
|
91
96
|
)
|
|
92
97
|
cache_span.__enter__()
|
|
93
98
|
|
|
@@ -97,18 +102,24 @@ def patch_redis_async_client(cls, is_cluster, set_db_data_fn):
|
|
|
97
102
|
op=db_properties["op"],
|
|
98
103
|
name=db_properties["description"],
|
|
99
104
|
origin=SPAN_ORIGIN,
|
|
105
|
+
only_if_parent=True,
|
|
100
106
|
)
|
|
101
107
|
db_span.__enter__()
|
|
102
108
|
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
db_span_data = get_db_data_fn(self)
|
|
110
|
+
db_client_span_data = _get_client_data(is_cluster, name, *args)
|
|
111
|
+
_update_span(db_span, db_span_data, db_client_span_data)
|
|
112
|
+
_create_breadcrumb(
|
|
113
|
+
db_properties["description"], db_span_data, db_client_span_data
|
|
114
|
+
)
|
|
105
115
|
|
|
106
116
|
value = await old_execute_command(self, name, *args, **kwargs)
|
|
107
117
|
|
|
108
118
|
db_span.__exit__(None, None, None)
|
|
109
119
|
|
|
110
120
|
if cache_span:
|
|
111
|
-
|
|
121
|
+
cache_span_data = _get_cache_data(self, cache_properties, value)
|
|
122
|
+
_update_span(cache_span, cache_span_data)
|
|
112
123
|
cache_span.__exit__(None, None, None)
|
|
113
124
|
|
|
114
125
|
return value
|