sentry-sdk 2.40.0__py2.py3-none-any.whl → 2.41.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.
Potentially problematic release.
This version of sentry-sdk might be problematic. Click here for more details.
- sentry_sdk/_metrics.py +81 -0
- sentry_sdk/_metrics_batcher.py +156 -0
- sentry_sdk/_types.py +27 -22
- sentry_sdk/ai/__init__.py +7 -0
- sentry_sdk/ai/utils.py +48 -0
- sentry_sdk/client.py +81 -30
- sentry_sdk/consts.py +4 -8
- sentry_sdk/envelope.py +3 -3
- sentry_sdk/integrations/anthropic.py +10 -2
- sentry_sdk/integrations/langchain.py +29 -4
- sentry_sdk/integrations/langgraph.py +5 -3
- sentry_sdk/integrations/logging.py +1 -1
- sentry_sdk/integrations/loguru.py +1 -1
- sentry_sdk/integrations/openai.py +3 -2
- sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +10 -2
- sentry_sdk/integrations/openai_agents/utils.py +35 -18
- sentry_sdk/integrations/threading.py +52 -8
- sentry_sdk/logger.py +1 -1
- sentry_sdk/tracing.py +0 -26
- sentry_sdk/transport.py +1 -17
- sentry_sdk/types.py +3 -0
- sentry_sdk/utils.py +17 -1
- {sentry_sdk-2.40.0.dist-info → sentry_sdk-2.41.0.dist-info}/METADATA +1 -1
- {sentry_sdk-2.40.0.dist-info → sentry_sdk-2.41.0.dist-info}/RECORD +28 -27
- sentry_sdk/metrics.py +0 -971
- {sentry_sdk-2.40.0.dist-info → sentry_sdk-2.41.0.dist-info}/WHEEL +0 -0
- {sentry_sdk-2.40.0.dist-info → sentry_sdk-2.41.0.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-2.40.0.dist-info → sentry_sdk-2.41.0.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-2.40.0.dist-info → sentry_sdk-2.41.0.dist-info}/top_level.txt +0 -0
|
@@ -4,7 +4,12 @@ from functools import wraps
|
|
|
4
4
|
|
|
5
5
|
import sentry_sdk
|
|
6
6
|
from sentry_sdk.ai.monitoring import set_ai_pipeline_name
|
|
7
|
-
from sentry_sdk.ai.utils import
|
|
7
|
+
from sentry_sdk.ai.utils import (
|
|
8
|
+
GEN_AI_ALLOWED_MESSAGE_ROLES,
|
|
9
|
+
normalize_message_roles,
|
|
10
|
+
set_data_normalized,
|
|
11
|
+
get_start_span_function,
|
|
12
|
+
)
|
|
8
13
|
from sentry_sdk.consts import OP, SPANDATA
|
|
9
14
|
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
10
15
|
from sentry_sdk.scope import should_send_default_pii
|
|
@@ -209,8 +214,18 @@ class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
|
|
|
209
214
|
_set_tools_on_span(span, all_params.get("tools"))
|
|
210
215
|
|
|
211
216
|
if should_send_default_pii() and self.include_prompts:
|
|
217
|
+
normalized_messages = [
|
|
218
|
+
{
|
|
219
|
+
"role": GEN_AI_ALLOWED_MESSAGE_ROLES.USER,
|
|
220
|
+
"content": {"type": "text", "text": prompt},
|
|
221
|
+
}
|
|
222
|
+
for prompt in prompts
|
|
223
|
+
]
|
|
212
224
|
set_data_normalized(
|
|
213
|
-
span,
|
|
225
|
+
span,
|
|
226
|
+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
227
|
+
normalized_messages,
|
|
228
|
+
unpack=False,
|
|
214
229
|
)
|
|
215
230
|
|
|
216
231
|
def on_chat_model_start(self, serialized, messages, *, run_id, **kwargs):
|
|
@@ -262,6 +277,8 @@ class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
|
|
|
262
277
|
normalized_messages.append(
|
|
263
278
|
self._normalize_langchain_message(message)
|
|
264
279
|
)
|
|
280
|
+
normalized_messages = normalize_message_roles(normalized_messages)
|
|
281
|
+
|
|
265
282
|
set_data_normalized(
|
|
266
283
|
span,
|
|
267
284
|
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
@@ -740,8 +757,12 @@ def _wrap_agent_executor_invoke(f):
|
|
|
740
757
|
and should_send_default_pii()
|
|
741
758
|
and integration.include_prompts
|
|
742
759
|
):
|
|
760
|
+
normalized_messages = normalize_message_roles([input])
|
|
743
761
|
set_data_normalized(
|
|
744
|
-
span,
|
|
762
|
+
span,
|
|
763
|
+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
764
|
+
normalized_messages,
|
|
765
|
+
unpack=False,
|
|
745
766
|
)
|
|
746
767
|
|
|
747
768
|
output = result.get("output")
|
|
@@ -791,8 +812,12 @@ def _wrap_agent_executor_stream(f):
|
|
|
791
812
|
and should_send_default_pii()
|
|
792
813
|
and integration.include_prompts
|
|
793
814
|
):
|
|
815
|
+
normalized_messages = normalize_message_roles([input])
|
|
794
816
|
set_data_normalized(
|
|
795
|
-
span,
|
|
817
|
+
span,
|
|
818
|
+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
819
|
+
normalized_messages,
|
|
820
|
+
unpack=False,
|
|
796
821
|
)
|
|
797
822
|
|
|
798
823
|
# Run the agent
|
|
@@ -2,7 +2,7 @@ from functools import wraps
|
|
|
2
2
|
from typing import Any, Callable, List, Optional
|
|
3
3
|
|
|
4
4
|
import sentry_sdk
|
|
5
|
-
from sentry_sdk.ai.utils import set_data_normalized
|
|
5
|
+
from sentry_sdk.ai.utils import set_data_normalized, normalize_message_roles
|
|
6
6
|
from sentry_sdk.consts import OP, SPANDATA
|
|
7
7
|
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
8
8
|
from sentry_sdk.scope import should_send_default_pii
|
|
@@ -180,10 +180,11 @@ def _wrap_pregel_invoke(f):
|
|
|
180
180
|
):
|
|
181
181
|
input_messages = _parse_langgraph_messages(args[0])
|
|
182
182
|
if input_messages:
|
|
183
|
+
normalized_input_messages = normalize_message_roles(input_messages)
|
|
183
184
|
set_data_normalized(
|
|
184
185
|
span,
|
|
185
186
|
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
186
|
-
|
|
187
|
+
normalized_input_messages,
|
|
187
188
|
unpack=False,
|
|
188
189
|
)
|
|
189
190
|
|
|
@@ -230,10 +231,11 @@ def _wrap_pregel_ainvoke(f):
|
|
|
230
231
|
):
|
|
231
232
|
input_messages = _parse_langgraph_messages(args[0])
|
|
232
233
|
if input_messages:
|
|
234
|
+
normalized_input_messages = normalize_message_roles(input_messages)
|
|
233
235
|
set_data_normalized(
|
|
234
236
|
span,
|
|
235
237
|
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
236
|
-
|
|
238
|
+
normalized_input_messages,
|
|
237
239
|
unpack=False,
|
|
238
240
|
)
|
|
239
241
|
|
|
@@ -409,7 +409,7 @@ class SentryLogsHandler(_BaseHandler):
|
|
|
409
409
|
attrs["logger.name"] = record.name
|
|
410
410
|
|
|
411
411
|
# noinspection PyProtectedMember
|
|
412
|
-
client.
|
|
412
|
+
client._capture_log(
|
|
413
413
|
{
|
|
414
414
|
"severity_text": otel_severity_text,
|
|
415
415
|
"severity_number": otel_severity_number,
|
|
@@ -193,7 +193,7 @@ def loguru_sentry_logs_handler(message):
|
|
|
193
193
|
if record.get("name"):
|
|
194
194
|
attrs["logger.name"] = record["name"]
|
|
195
195
|
|
|
196
|
-
client.
|
|
196
|
+
client._capture_log(
|
|
197
197
|
{
|
|
198
198
|
"severity_text": otel_severity_text,
|
|
199
199
|
"severity_number": otel_severity_number,
|
|
@@ -3,7 +3,7 @@ from functools import wraps
|
|
|
3
3
|
import sentry_sdk
|
|
4
4
|
from sentry_sdk import consts
|
|
5
5
|
from sentry_sdk.ai.monitoring import record_token_usage
|
|
6
|
-
from sentry_sdk.ai.utils import set_data_normalized
|
|
6
|
+
from sentry_sdk.ai.utils import set_data_normalized, normalize_message_roles
|
|
7
7
|
from sentry_sdk.consts import SPANDATA
|
|
8
8
|
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
9
9
|
from sentry_sdk.scope import should_send_default_pii
|
|
@@ -182,8 +182,9 @@ def _set_input_data(span, kwargs, operation, integration):
|
|
|
182
182
|
and should_send_default_pii()
|
|
183
183
|
and integration.include_prompts
|
|
184
184
|
):
|
|
185
|
+
normalized_messages = normalize_message_roles(messages)
|
|
185
186
|
set_data_normalized(
|
|
186
|
-
span, SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
187
|
+
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, normalized_messages, unpack=False
|
|
187
188
|
)
|
|
188
189
|
|
|
189
190
|
# Input attributes: Common
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import sentry_sdk
|
|
2
|
-
from sentry_sdk.ai.utils import
|
|
2
|
+
from sentry_sdk.ai.utils import (
|
|
3
|
+
get_start_span_function,
|
|
4
|
+
set_data_normalized,
|
|
5
|
+
normalize_message_roles,
|
|
6
|
+
)
|
|
3
7
|
from sentry_sdk.consts import OP, SPANDATA
|
|
4
8
|
from sentry_sdk.scope import should_send_default_pii
|
|
5
9
|
from sentry_sdk.utils import safe_serialize
|
|
@@ -56,8 +60,12 @@ def invoke_agent_span(context, agent, kwargs):
|
|
|
56
60
|
)
|
|
57
61
|
|
|
58
62
|
if len(messages) > 0:
|
|
63
|
+
normalized_messages = normalize_message_roles(messages)
|
|
59
64
|
set_data_normalized(
|
|
60
|
-
span,
|
|
65
|
+
span,
|
|
66
|
+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
67
|
+
normalized_messages,
|
|
68
|
+
unpack=False,
|
|
61
69
|
)
|
|
62
70
|
|
|
63
71
|
_set_agent_data(span, agent)
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import sentry_sdk
|
|
2
|
-
from sentry_sdk.ai.utils import
|
|
2
|
+
from sentry_sdk.ai.utils import (
|
|
3
|
+
GEN_AI_ALLOWED_MESSAGE_ROLES,
|
|
4
|
+
normalize_message_roles,
|
|
5
|
+
set_data_normalized,
|
|
6
|
+
normalize_message_role,
|
|
7
|
+
)
|
|
3
8
|
from sentry_sdk.consts import SPANDATA, SPANSTATUS, OP
|
|
4
9
|
from sentry_sdk.integrations import DidNotEnable
|
|
5
10
|
from sentry_sdk.scope import should_send_default_pii
|
|
@@ -94,35 +99,47 @@ def _set_input_data(span, get_response_kwargs):
|
|
|
94
99
|
# type: (sentry_sdk.tracing.Span, dict[str, Any]) -> None
|
|
95
100
|
if not should_send_default_pii():
|
|
96
101
|
return
|
|
102
|
+
request_messages = []
|
|
97
103
|
|
|
98
|
-
messages_by_role = {
|
|
99
|
-
"system": [],
|
|
100
|
-
"user": [],
|
|
101
|
-
"assistant": [],
|
|
102
|
-
"tool": [],
|
|
103
|
-
} # type: (dict[str, list[Any]])
|
|
104
104
|
system_instructions = get_response_kwargs.get("system_instructions")
|
|
105
105
|
if system_instructions:
|
|
106
|
-
|
|
106
|
+
request_messages.append(
|
|
107
|
+
{
|
|
108
|
+
"role": GEN_AI_ALLOWED_MESSAGE_ROLES.SYSTEM,
|
|
109
|
+
"content": [{"type": "text", "text": system_instructions}],
|
|
110
|
+
}
|
|
111
|
+
)
|
|
107
112
|
|
|
108
113
|
for message in get_response_kwargs.get("input", []):
|
|
109
114
|
if "role" in message:
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
normalized_role = normalize_message_role(message.get("role"))
|
|
116
|
+
request_messages.append(
|
|
117
|
+
{
|
|
118
|
+
"role": normalized_role,
|
|
119
|
+
"content": [{"type": "text", "text": message.get("content")}],
|
|
120
|
+
}
|
|
112
121
|
)
|
|
113
122
|
else:
|
|
114
123
|
if message.get("type") == "function_call":
|
|
115
|
-
|
|
124
|
+
request_messages.append(
|
|
125
|
+
{
|
|
126
|
+
"role": GEN_AI_ALLOWED_MESSAGE_ROLES.ASSISTANT,
|
|
127
|
+
"content": [message],
|
|
128
|
+
}
|
|
129
|
+
)
|
|
116
130
|
elif message.get("type") == "function_call_output":
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
131
|
+
request_messages.append(
|
|
132
|
+
{
|
|
133
|
+
"role": GEN_AI_ALLOWED_MESSAGE_ROLES.TOOL,
|
|
134
|
+
"content": [message],
|
|
135
|
+
}
|
|
136
|
+
)
|
|
123
137
|
|
|
124
138
|
set_data_normalized(
|
|
125
|
-
span,
|
|
139
|
+
span,
|
|
140
|
+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
|
|
141
|
+
normalize_message_roles(request_messages),
|
|
142
|
+
unpack=False,
|
|
126
143
|
)
|
|
127
144
|
|
|
128
145
|
|
|
@@ -2,6 +2,7 @@ import sys
|
|
|
2
2
|
import warnings
|
|
3
3
|
from functools import wraps
|
|
4
4
|
from threading import Thread, current_thread
|
|
5
|
+
from concurrent.futures import ThreadPoolExecutor, Future
|
|
5
6
|
|
|
6
7
|
import sentry_sdk
|
|
7
8
|
from sentry_sdk.integrations import Integration
|
|
@@ -24,6 +25,7 @@ if TYPE_CHECKING:
|
|
|
24
25
|
from sentry_sdk._types import ExcInfo
|
|
25
26
|
|
|
26
27
|
F = TypeVar("F", bound=Callable[..., Any])
|
|
28
|
+
T = TypeVar("T", bound=Any)
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class ThreadingIntegration(Integration):
|
|
@@ -59,6 +61,15 @@ class ThreadingIntegration(Integration):
|
|
|
59
61
|
django_version = None
|
|
60
62
|
channels_version = None
|
|
61
63
|
|
|
64
|
+
is_async_emulated_with_threads = (
|
|
65
|
+
sys.version_info < (3, 9)
|
|
66
|
+
and channels_version is not None
|
|
67
|
+
and channels_version < "4.0.0"
|
|
68
|
+
and django_version is not None
|
|
69
|
+
and django_version >= (3, 0)
|
|
70
|
+
and django_version < (4, 0)
|
|
71
|
+
)
|
|
72
|
+
|
|
62
73
|
@wraps(old_start)
|
|
63
74
|
def sentry_start(self, *a, **kw):
|
|
64
75
|
# type: (Thread, *Any, **Any) -> Any
|
|
@@ -67,14 +78,7 @@ class ThreadingIntegration(Integration):
|
|
|
67
78
|
return old_start(self, *a, **kw)
|
|
68
79
|
|
|
69
80
|
if integration.propagate_scope:
|
|
70
|
-
if
|
|
71
|
-
sys.version_info < (3, 9)
|
|
72
|
-
and channels_version is not None
|
|
73
|
-
and channels_version < "4.0.0"
|
|
74
|
-
and django_version is not None
|
|
75
|
-
and django_version >= (3, 0)
|
|
76
|
-
and django_version < (4, 0)
|
|
77
|
-
):
|
|
81
|
+
if is_async_emulated_with_threads:
|
|
78
82
|
warnings.warn(
|
|
79
83
|
"There is a known issue with Django channels 2.x and 3.x when using Python 3.8 or older. "
|
|
80
84
|
"(Async support is emulated using threads and some Sentry data may be leaked between those threads.) "
|
|
@@ -109,6 +113,9 @@ class ThreadingIntegration(Integration):
|
|
|
109
113
|
return old_start(self, *a, **kw)
|
|
110
114
|
|
|
111
115
|
Thread.start = sentry_start # type: ignore
|
|
116
|
+
ThreadPoolExecutor.submit = _wrap_threadpool_executor_submit( # type: ignore
|
|
117
|
+
ThreadPoolExecutor.submit, is_async_emulated_with_threads
|
|
118
|
+
)
|
|
112
119
|
|
|
113
120
|
|
|
114
121
|
def _wrap_run(isolation_scope_to_use, current_scope_to_use, old_run_func):
|
|
@@ -134,6 +141,43 @@ def _wrap_run(isolation_scope_to_use, current_scope_to_use, old_run_func):
|
|
|
134
141
|
return run # type: ignore
|
|
135
142
|
|
|
136
143
|
|
|
144
|
+
def _wrap_threadpool_executor_submit(func, is_async_emulated_with_threads):
|
|
145
|
+
# type: (Callable[..., Future[T]], bool) -> Callable[..., Future[T]]
|
|
146
|
+
"""
|
|
147
|
+
Wrap submit call to propagate scopes on task submission.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
@wraps(func)
|
|
151
|
+
def sentry_submit(self, fn, *args, **kwargs):
|
|
152
|
+
# type: (ThreadPoolExecutor, Callable[..., T], *Any, **Any) -> Future[T]
|
|
153
|
+
integration = sentry_sdk.get_client().get_integration(ThreadingIntegration)
|
|
154
|
+
if integration is None:
|
|
155
|
+
return func(self, fn, *args, **kwargs)
|
|
156
|
+
|
|
157
|
+
if integration.propagate_scope and is_async_emulated_with_threads:
|
|
158
|
+
isolation_scope = sentry_sdk.get_isolation_scope()
|
|
159
|
+
current_scope = sentry_sdk.get_current_scope()
|
|
160
|
+
elif integration.propagate_scope:
|
|
161
|
+
isolation_scope = sentry_sdk.get_isolation_scope().fork()
|
|
162
|
+
current_scope = sentry_sdk.get_current_scope().fork()
|
|
163
|
+
else:
|
|
164
|
+
isolation_scope = None
|
|
165
|
+
current_scope = None
|
|
166
|
+
|
|
167
|
+
def wrapped_fn(*args, **kwargs):
|
|
168
|
+
# type: (*Any, **Any) -> Any
|
|
169
|
+
if isolation_scope is not None and current_scope is not None:
|
|
170
|
+
with use_isolation_scope(isolation_scope):
|
|
171
|
+
with use_scope(current_scope):
|
|
172
|
+
return fn(*args, **kwargs)
|
|
173
|
+
|
|
174
|
+
return fn(*args, **kwargs)
|
|
175
|
+
|
|
176
|
+
return func(self, wrapped_fn, *args, **kwargs)
|
|
177
|
+
|
|
178
|
+
return sentry_submit
|
|
179
|
+
|
|
180
|
+
|
|
137
181
|
def _capture_exception():
|
|
138
182
|
# type: () -> ExcInfo
|
|
139
183
|
exc_info = sys.exc_info()
|
sentry_sdk/logger.py
CHANGED
sentry_sdk/tracing.py
CHANGED
|
@@ -276,7 +276,6 @@ class Span:
|
|
|
276
276
|
"hub",
|
|
277
277
|
"_context_manager_state",
|
|
278
278
|
"_containing_transaction",
|
|
279
|
-
"_local_aggregator",
|
|
280
279
|
"scope",
|
|
281
280
|
"origin",
|
|
282
281
|
"name",
|
|
@@ -345,7 +344,6 @@ class Span:
|
|
|
345
344
|
self.timestamp = None # type: Optional[datetime]
|
|
346
345
|
|
|
347
346
|
self._span_recorder = None # type: Optional[_SpanRecorder]
|
|
348
|
-
self._local_aggregator = None # type: Optional[LocalAggregator]
|
|
349
347
|
|
|
350
348
|
self.update_active_thread()
|
|
351
349
|
self.set_profiler_id(get_profiler_id())
|
|
@@ -383,13 +381,6 @@ class Span:
|
|
|
383
381
|
# type: (str) -> None
|
|
384
382
|
self._span_id = value
|
|
385
383
|
|
|
386
|
-
def _get_local_aggregator(self):
|
|
387
|
-
# type: (...) -> LocalAggregator
|
|
388
|
-
rv = self._local_aggregator
|
|
389
|
-
if rv is None:
|
|
390
|
-
rv = self._local_aggregator = LocalAggregator()
|
|
391
|
-
return rv
|
|
392
|
-
|
|
393
384
|
def __repr__(self):
|
|
394
385
|
# type: () -> str
|
|
395
386
|
return (
|
|
@@ -741,11 +732,6 @@ class Span:
|
|
|
741
732
|
if self.status:
|
|
742
733
|
self._tags["status"] = self.status
|
|
743
734
|
|
|
744
|
-
if self._local_aggregator is not None:
|
|
745
|
-
metrics_summary = self._local_aggregator.to_json()
|
|
746
|
-
if metrics_summary:
|
|
747
|
-
rv["_metrics_summary"] = metrics_summary
|
|
748
|
-
|
|
749
735
|
if len(self._measurements) > 0:
|
|
750
736
|
rv["measurements"] = self._measurements
|
|
751
737
|
|
|
@@ -1122,13 +1108,6 @@ class Transaction(Span):
|
|
|
1122
1108
|
|
|
1123
1109
|
event["measurements"] = self._measurements
|
|
1124
1110
|
|
|
1125
|
-
# This is here since `to_json` is not invoked. This really should
|
|
1126
|
-
# be gone when we switch to onlyspans.
|
|
1127
|
-
if self._local_aggregator is not None:
|
|
1128
|
-
metrics_summary = self._local_aggregator.to_json()
|
|
1129
|
-
if metrics_summary:
|
|
1130
|
-
event["_metrics_summary"] = metrics_summary
|
|
1131
|
-
|
|
1132
1111
|
return scope.capture_event(event)
|
|
1133
1112
|
|
|
1134
1113
|
def set_measurement(self, name, value, unit=""):
|
|
@@ -1505,8 +1484,3 @@ from sentry_sdk.tracing_utils import (
|
|
|
1505
1484
|
has_tracing_enabled,
|
|
1506
1485
|
maybe_create_breadcrumbs_from_span,
|
|
1507
1486
|
)
|
|
1508
|
-
|
|
1509
|
-
with warnings.catch_warnings():
|
|
1510
|
-
# The code in this file which uses `LocalAggregator` is only called from the deprecated `metrics` module.
|
|
1511
|
-
warnings.simplefilter("ignore", DeprecationWarning)
|
|
1512
|
-
from sentry_sdk.metrics import LocalAggregator
|
sentry_sdk/transport.py
CHANGED
|
@@ -171,17 +171,7 @@ def _parse_rate_limits(header, now=None):
|
|
|
171
171
|
|
|
172
172
|
retry_after = now + timedelta(seconds=int(retry_after_val))
|
|
173
173
|
for category in categories and categories.split(";") or (None,):
|
|
174
|
-
|
|
175
|
-
try:
|
|
176
|
-
namespaces = parameters[4].split(";")
|
|
177
|
-
except IndexError:
|
|
178
|
-
namespaces = []
|
|
179
|
-
|
|
180
|
-
if not namespaces or "custom" in namespaces:
|
|
181
|
-
yield category, retry_after # type: ignore
|
|
182
|
-
|
|
183
|
-
else:
|
|
184
|
-
yield category, retry_after # type: ignore
|
|
174
|
+
yield category, retry_after # type: ignore
|
|
185
175
|
except (LookupError, ValueError):
|
|
186
176
|
continue
|
|
187
177
|
|
|
@@ -417,12 +407,6 @@ class BaseHttpTransport(Transport):
|
|
|
417
407
|
# type: (str) -> bool
|
|
418
408
|
def _disabled(bucket):
|
|
419
409
|
# type: (Any) -> bool
|
|
420
|
-
|
|
421
|
-
# The envelope item type used for metrics is statsd
|
|
422
|
-
# whereas the rate limit category is metric_bucket
|
|
423
|
-
if bucket == "statsd":
|
|
424
|
-
bucket = "metric_bucket"
|
|
425
|
-
|
|
426
410
|
ts = self._disabled_until.get(bucket)
|
|
427
411
|
return ts is not None and ts > datetime.now(timezone.utc)
|
|
428
412
|
|
sentry_sdk/types.py
CHANGED
|
@@ -21,6 +21,7 @@ if TYPE_CHECKING:
|
|
|
21
21
|
Log,
|
|
22
22
|
MonitorConfig,
|
|
23
23
|
SamplingContext,
|
|
24
|
+
Metric,
|
|
24
25
|
)
|
|
25
26
|
else:
|
|
26
27
|
from typing import Any
|
|
@@ -35,6 +36,7 @@ else:
|
|
|
35
36
|
Log = Any
|
|
36
37
|
MonitorConfig = Any
|
|
37
38
|
SamplingContext = Any
|
|
39
|
+
Metric = Any
|
|
38
40
|
|
|
39
41
|
|
|
40
42
|
__all__ = (
|
|
@@ -46,4 +48,5 @@ __all__ = (
|
|
|
46
48
|
"Log",
|
|
47
49
|
"MonitorConfig",
|
|
48
50
|
"SamplingContext",
|
|
51
|
+
"Metric",
|
|
49
52
|
)
|
sentry_sdk/utils.py
CHANGED
|
@@ -59,7 +59,7 @@ if TYPE_CHECKING:
|
|
|
59
59
|
|
|
60
60
|
from gevent.hub import Hub
|
|
61
61
|
|
|
62
|
-
from sentry_sdk._types import Event, ExcInfo, Log, Hint
|
|
62
|
+
from sentry_sdk._types import Event, ExcInfo, Log, Hint, Metric
|
|
63
63
|
|
|
64
64
|
P = ParamSpec("P")
|
|
65
65
|
R = TypeVar("R")
|
|
@@ -2013,3 +2013,19 @@ def get_before_send_log(options):
|
|
|
2013
2013
|
return options.get("before_send_log") or options["_experiments"].get(
|
|
2014
2014
|
"before_send_log"
|
|
2015
2015
|
)
|
|
2016
|
+
|
|
2017
|
+
|
|
2018
|
+
def has_metrics_enabled(options):
|
|
2019
|
+
# type: (Optional[dict[str, Any]]) -> bool
|
|
2020
|
+
if options is None:
|
|
2021
|
+
return False
|
|
2022
|
+
|
|
2023
|
+
return bool(options["_experiments"].get("enable_metrics", False))
|
|
2024
|
+
|
|
2025
|
+
|
|
2026
|
+
def get_before_send_metric(options):
|
|
2027
|
+
# type: (Optional[dict[str, Any]]) -> Optional[Callable[[Metric, Hint], Optional[Metric]]]
|
|
2028
|
+
if options is None:
|
|
2029
|
+
return None
|
|
2030
|
+
|
|
2031
|
+
return options["_experiments"].get("before_send_metric")
|
|
@@ -3,19 +3,20 @@ sentry_sdk/_compat.py,sha256=Pxcg6cUYPiOoXIFfLI_H3ATb7SfrcXOeZdzpeWv3umI,3116
|
|
|
3
3
|
sentry_sdk/_init_implementation.py,sha256=WL54d8nggjRunBm3XlG-sWSx4yS5lpYYggd7YBWpuVk,2559
|
|
4
4
|
sentry_sdk/_log_batcher.py,sha256=bBpspIlf1ejxlbudo17bZOSir226LGAdjDe_3kHkOro,5085
|
|
5
5
|
sentry_sdk/_lru_cache.py,sha256=phZMBm9EKU1m67OOApnKCffnlWAlVz9bYjig7CglQuk,1229
|
|
6
|
+
sentry_sdk/_metrics.py,sha256=ov1aCqPvcmnDba43HHjWT2flqNPfA5Fa0O0iopcnZpI,2044
|
|
7
|
+
sentry_sdk/_metrics_batcher.py,sha256=1W7nmijIsiFAsNfg2jdw6Lm4mwlAFFSnx_Oc2zQmASc,4612
|
|
6
8
|
sentry_sdk/_queue.py,sha256=UUzbmliDYmdVYiDA32NMYkX369ElWMFNSj5kodqVQZE,11250
|
|
7
|
-
sentry_sdk/_types.py,sha256=
|
|
9
|
+
sentry_sdk/_types.py,sha256=ld5Y0yMsLxd6P6tPifw3IqUg8bpFE0hgxPDUmn6B9Xg,10422
|
|
8
10
|
sentry_sdk/_werkzeug.py,sha256=m3GPf-jHd8v3eVOfBHaKw5f0uHoLkXrSO1EcY-8EisY,3734
|
|
9
11
|
sentry_sdk/api.py,sha256=OkwQ2tA5YASJ77wLOteUdv_woPF4wL_JTOAMxe9z8k4,15282
|
|
10
12
|
sentry_sdk/attachments.py,sha256=0Dylhm065O6hNFjB40fWCd5Hg4qWSXndmi1TPWglZkI,3109
|
|
11
|
-
sentry_sdk/client.py,sha256=
|
|
12
|
-
sentry_sdk/consts.py,sha256=
|
|
13
|
+
sentry_sdk/client.py,sha256=ilR4V9_m7tknWlMK9Czq9lHn7ccuU7lfu6B4l_oRTFk,40520
|
|
14
|
+
sentry_sdk/consts.py,sha256=4buYhBmsKLTstqWizghIrHUFmKwo3PikaBP75mic_8w,50559
|
|
13
15
|
sentry_sdk/debug.py,sha256=ddBehQlAuQC1sg1XO-N4N3diZ0x0iT5RWJwFdrtcsjw,1019
|
|
14
|
-
sentry_sdk/envelope.py,sha256=
|
|
16
|
+
sentry_sdk/envelope.py,sha256=1nqp_DMw66MYtrszRiiCuodyi3JKcOiQodEMkD6uZ_c,10473
|
|
15
17
|
sentry_sdk/feature_flags.py,sha256=savtmWAHjAvgw2m_KWW8mUagjLhAXCm3jjscmBlfIJ4,2232
|
|
16
18
|
sentry_sdk/hub.py,sha256=jg7UqYiJFJ1dknVCNT4_E5lIBfrCFQdWwnJrhgScVNg,25748
|
|
17
|
-
sentry_sdk/logger.py,sha256=
|
|
18
|
-
sentry_sdk/metrics.py,sha256=HBlrCca7XWgxYwxgPBWkBQOXtUqOFQxW4hNdtAFl1uc,29961
|
|
19
|
+
sentry_sdk/logger.py,sha256=6tD1sQq3NKAIRgTjRSJyxEvDZMeShj5aUfMhY9hLYIE,2458
|
|
19
20
|
sentry_sdk/monitor.py,sha256=52CG1m2e8okFDVoTpbqfm9zeeaLa0ciC_r9x2RiXuDg,3639
|
|
20
21
|
sentry_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
22
|
sentry_sdk/scope.py,sha256=gTdGB0eUvjS1TMKvRHckB5AJnBGFGpwps8uPh--KI8k,63934
|
|
@@ -24,15 +25,15 @@ sentry_sdk/serializer.py,sha256=0-WdtKYwmGEM7nVxmOeRAXjC0DVdIHCymQpRuIHDBX0,1353
|
|
|
24
25
|
sentry_sdk/session.py,sha256=BXWHf5Opg9yx7jKe-_iHxF6LDJw9Jnu7NfHxo3UQRpw,5589
|
|
25
26
|
sentry_sdk/sessions.py,sha256=e7Jv8McW3QZp3H1GuI_CA_ezq_G0ZWY6nK0ZLqJRdNI,9172
|
|
26
27
|
sentry_sdk/spotlight.py,sha256=93kdd8KxdLfcPaxFnFuqHgYAAL4FCfpK1hiiPoD7Ac4,8678
|
|
27
|
-
sentry_sdk/tracing.py,sha256=
|
|
28
|
+
sentry_sdk/tracing.py,sha256=lJG5TmA7mz7-RfJEr34ydgBf-lebRegejHkhdNsHH08,51747
|
|
28
29
|
sentry_sdk/tracing_utils.py,sha256=XXdU_YH0Shuk2pkeUGZrZgi_CTQFuf42Plgu4qQq978,39288
|
|
29
|
-
sentry_sdk/transport.py,sha256=
|
|
30
|
-
sentry_sdk/types.py,sha256=
|
|
31
|
-
sentry_sdk/utils.py,sha256=
|
|
30
|
+
sentry_sdk/transport.py,sha256=NzlBS5liRSh0Fm7Zi7sPdZG82uECw9myECs_JrClqkg,31878
|
|
31
|
+
sentry_sdk/types.py,sha256=A92AqvfrGQZ9KY6FaUjKfL9F1HK7Ui3heQilVzfzYCs,1269
|
|
32
|
+
sentry_sdk/utils.py,sha256=ytlUxHsGpnUQgnFBmDoEiFLq0iZ3cxJbPQi88HMniiA,62176
|
|
32
33
|
sentry_sdk/worker.py,sha256=VSMaigRMbInVyupSFpBC42bft2oIViea-0C_d9ThnIo,4464
|
|
33
|
-
sentry_sdk/ai/__init__.py,sha256=
|
|
34
|
+
sentry_sdk/ai/__init__.py,sha256=I7GRMQEYTV0bXzEIE0iAJjAn6Te-dPM5uGyJ9KS-6hI,193
|
|
34
35
|
sentry_sdk/ai/monitoring.py,sha256=bS_KneWCAL9ehml5XiyficoPVx4DUUG6acbH3cjP3I8,5057
|
|
35
|
-
sentry_sdk/ai/utils.py,sha256=
|
|
36
|
+
sentry_sdk/ai/utils.py,sha256=StHk8b34APp6mHGp9oPD7aPRROKXJv5KqM8h8c4Hv9s,3270
|
|
36
37
|
sentry_sdk/crons/__init__.py,sha256=3Zt6g1-pZZ12uRKKsC8QLm3XgJ4K1VYxgVpNNUygOZY,221
|
|
37
38
|
sentry_sdk/crons/api.py,sha256=mk-UB8Im2LU2rJFdE-TV302EaKnf8kAjwEL0bIV0Hzc,1767
|
|
38
39
|
sentry_sdk/crons/consts.py,sha256=dXqJk5meBSu5rjlGpqAOlkpACnuUi7svQnAFoy1ZNUU,87
|
|
@@ -41,7 +42,7 @@ sentry_sdk/integrations/__init__.py,sha256=qtU1pBq6CEeAKPikc9cfARULouHYkl8jbXJpm
|
|
|
41
42
|
sentry_sdk/integrations/_asgi_common.py,sha256=Ypg7IctB3iPPY60ebVlzChzgT8GeGpZ0YH8VvJNDlEY,3187
|
|
42
43
|
sentry_sdk/integrations/_wsgi_common.py,sha256=A1-X7l1pZCcrbUhRHkmdKiK_EemEZjn7xToJIvlEuFM,7558
|
|
43
44
|
sentry_sdk/integrations/aiohttp.py,sha256=_rfDKx1arvVQwcC20vh7HG80p8XtgzqKB3iBuPYZy8A,12895
|
|
44
|
-
sentry_sdk/integrations/anthropic.py,sha256=
|
|
45
|
+
sentry_sdk/integrations/anthropic.py,sha256=AeGNc8WGXhqtSk9oZcxcEAp1lRvQT16i6HOKUGfat2M,13935
|
|
45
46
|
sentry_sdk/integrations/argv.py,sha256=GIY7TBFETF8Z0fDzqTXEJldt5XXCDdFNZxpGxP7EPaU,911
|
|
46
47
|
sentry_sdk/integrations/ariadne.py,sha256=C-zKlOrU7jvTWmQHZx0M0tAZNkPPo7Z5-5jXDD92LiU,5834
|
|
47
48
|
sentry_sdk/integrations/arq.py,sha256=yDPdWJa3ZgnGLwFzavIylIafEVN0qqSSgL4kUHxQF70,7881
|
|
@@ -71,15 +72,15 @@ sentry_sdk/integrations/graphene.py,sha256=I6ZJ8Apd9dO9XPVvZY7I46-v1eXOW1C1rAkWw
|
|
|
71
72
|
sentry_sdk/integrations/httpx.py,sha256=WwUulqzBLoGGqWUUdQg_MThwQUKzBXnA-m3g_1GOpCE,5866
|
|
72
73
|
sentry_sdk/integrations/huey.py,sha256=wlyxjeWqqJp1X5S3neD5FiZjXcyznm1dl8_u1wIo76U,5443
|
|
73
74
|
sentry_sdk/integrations/huggingface_hub.py,sha256=B5z0--bC2tEDtWl5V7xAqM4234yhY_RYbnkZGgqC8PA,14952
|
|
74
|
-
sentry_sdk/integrations/langchain.py,sha256=
|
|
75
|
-
sentry_sdk/integrations/langgraph.py,sha256=
|
|
75
|
+
sentry_sdk/integrations/langchain.py,sha256=WeqF7F0HZKR8Fra4RAivgxtxt8BsgMxua6r4n-sLX84,30302
|
|
76
|
+
sentry_sdk/integrations/langgraph.py,sha256=3wzDDwHVmuxF1vEiVoJqyc7r7hqK9VJoOmdgKNwbcE0,11238
|
|
76
77
|
sentry_sdk/integrations/launchdarkly.py,sha256=L5yE9NBRon8JPYzO6XT-dA4YkvNcrUfK4nD5fycSXM0,1934
|
|
77
78
|
sentry_sdk/integrations/litellm.py,sha256=WCwjsIZBxJ2Rk2yAWJBUxyNehgO6B37a_X2JJcvM4OY,8858
|
|
78
79
|
sentry_sdk/integrations/litestar.py,sha256=0BkfynHkxERshbxycwHDnpjzGx31c5ipYvBYqprAoHY,11830
|
|
79
|
-
sentry_sdk/integrations/logging.py,sha256=
|
|
80
|
-
sentry_sdk/integrations/loguru.py,sha256=
|
|
80
|
+
sentry_sdk/integrations/logging.py,sha256=L1f3dej3Zdn9wyB5_mzvzyk4bF-HvFFmhGegfBfMPnA,13892
|
|
81
|
+
sentry_sdk/integrations/loguru.py,sha256=JmIiVnkjbEzb8dRsFln4T7Ft_GULyXEt7w5t-p5Zdt4,6202
|
|
81
82
|
sentry_sdk/integrations/modules.py,sha256=vzLx3Erg77Vl4mnUvAgTg_3teAuWy7zylFpAidBI9I0,820
|
|
82
|
-
sentry_sdk/integrations/openai.py,sha256=
|
|
83
|
+
sentry_sdk/integrations/openai.py,sha256=zvsW4-ypH_n4B2EIYYQ3gheJDzNOxZRgr5ApPrzCOE8,24160
|
|
83
84
|
sentry_sdk/integrations/openfeature.py,sha256=-vvdrN4fK0Xhu2ip41bkPIPEqdzv8xzmLu9wRlI2xPA,1131
|
|
84
85
|
sentry_sdk/integrations/pure_eval.py,sha256=R2UuFCtQ_ShTIZJKPn9RUD06lbc6mug4Mv8S1_mo1j0,4605
|
|
85
86
|
sentry_sdk/integrations/pymongo.py,sha256=cPpMGEbXHlV6HTHgmIDL1F-x3w7ZMROXVb4eUhLs3bw,6380
|
|
@@ -98,7 +99,7 @@ sentry_sdk/integrations/statsig.py,sha256=-e57hxHfHo1S13YQKObV65q_UvREyxbR56fnf7
|
|
|
98
99
|
sentry_sdk/integrations/stdlib.py,sha256=vgB9weDGh455vBwmUSgcQRgzViKstu3O0syOthCn_H0,8831
|
|
99
100
|
sentry_sdk/integrations/strawberry.py,sha256=u7Lk4u3sNEycdSmY1nQBzYKmqI-mO8BWKAAJkCSuTRA,14126
|
|
100
101
|
sentry_sdk/integrations/sys_exit.py,sha256=AwShgGBWPdiY25aOWDLRAs2RBUKm5T3CrL-Q-zAk0l4,2493
|
|
101
|
-
sentry_sdk/integrations/threading.py,sha256=
|
|
102
|
+
sentry_sdk/integrations/threading.py,sha256=0lNxcMLN7Z5DwLg9d1Of7lgGcMOggsM76bU35hIOGXA,7109
|
|
102
103
|
sentry_sdk/integrations/tornado.py,sha256=Qcft8FZxdVICnaa1AhsDB262sInEQZPf-pvgI-Agjmc,7206
|
|
103
104
|
sentry_sdk/integrations/trytond.py,sha256=BaLCNqQeRWDbHHDEelS5tmj-p_CrbmtGEHIn6JfzEFE,1651
|
|
104
105
|
sentry_sdk/integrations/typer.py,sha256=FQrFgpR9t6yQWF-oWCI9KJLFioEnA2c_1BEtYV-mPAs,1815
|
|
@@ -125,7 +126,7 @@ sentry_sdk/integrations/grpc/aio/client.py,sha256=3zfF3XkpzR717BpY1ehxi72jDUvT8X
|
|
|
125
126
|
sentry_sdk/integrations/grpc/aio/server.py,sha256=SCkdikPZRdWyrlnZewsSGpPk4v6AsdSApVAbO-lf_Lk,4019
|
|
126
127
|
sentry_sdk/integrations/openai_agents/__init__.py,sha256=-ydqG0sFIrvJlT9JHO58EZpCAzyy9J59Av8dxn0fHuw,1424
|
|
127
128
|
sentry_sdk/integrations/openai_agents/consts.py,sha256=PTb3vlqkuMPktu21ALK72o5WMIX4-cewTEiTRdHKFdQ,38
|
|
128
|
-
sentry_sdk/integrations/openai_agents/utils.py,sha256=
|
|
129
|
+
sentry_sdk/integrations/openai_agents/utils.py,sha256=fa3r6iHLjTtrU2dHM_7D_0lDQAHR3CUSutIa6Wf7efg,6808
|
|
129
130
|
sentry_sdk/integrations/openai_agents/patches/__init__.py,sha256=I7C9JZ70Mf8PV3wPdFsxTqvcYl4TYUgSZYfNU2Spb7Y,231
|
|
130
131
|
sentry_sdk/integrations/openai_agents/patches/agent_run.py,sha256=GPBV-j8YnHOrJAhdhu_tphe14z7G0-riFVmjFNDgy0s,5773
|
|
131
132
|
sentry_sdk/integrations/openai_agents/patches/models.py,sha256=DtwqCmSsYFlhRZquKM2jiTOnnAg97eyCTtJYZkWqdww,1405
|
|
@@ -136,7 +137,7 @@ sentry_sdk/integrations/openai_agents/spans/agent_workflow.py,sha256=fdRSThD31Tc
|
|
|
136
137
|
sentry_sdk/integrations/openai_agents/spans/ai_client.py,sha256=gCZrl1vpBmf8vzDTSLCvoZg-x_TvMUFTLOxh4Vy_4OY,1292
|
|
137
138
|
sentry_sdk/integrations/openai_agents/spans/execute_tool.py,sha256=tqtDIzaxhxJUE-XEvm2dSyJV65UXJ7Mr23C6NTt6ZJE,1411
|
|
138
139
|
sentry_sdk/integrations/openai_agents/spans/handoff.py,sha256=MBhzy7MpvPGwQTPT5TFcOnmSPiSH_uadQ5wvksueIik,525
|
|
139
|
-
sentry_sdk/integrations/openai_agents/spans/invoke_agent.py,sha256=
|
|
140
|
+
sentry_sdk/integrations/openai_agents/spans/invoke_agent.py,sha256=AXiXuJjcvgj_M6NWxHg-OVWld7-nb8VQe3Iq1IEIxOk,2493
|
|
140
141
|
sentry_sdk/integrations/opentelemetry/__init__.py,sha256=emNL5aAq_NhK0PZmfX_g4GIdvBS6nHqGrjrIgrdC5m8,229
|
|
141
142
|
sentry_sdk/integrations/opentelemetry/consts.py,sha256=fYL6FIAEfnGZGBhFn5X7aRyHxihSPqAKKqMLhf5Gniw,143
|
|
142
143
|
sentry_sdk/integrations/opentelemetry/integration.py,sha256=CWp6hFFMqoR7wcuwTRbRO-1iVch4A6oOB3RuHWeX9GQ,1791
|
|
@@ -161,9 +162,9 @@ sentry_sdk/profiler/__init__.py,sha256=3PI3bHk9RSkkOXZKN84DDedk_7M65EiqqaIGo-DYs
|
|
|
161
162
|
sentry_sdk/profiler/continuous_profiler.py,sha256=7Qb75TaKLNYxMA97wO-qEpDVqxPQWOLUi2rnUm6_Ci0,23066
|
|
162
163
|
sentry_sdk/profiler/transaction_profiler.py,sha256=e3MsUqs-YIp6-nmzpmBYGoWWIF7RyuSGu24Dj-8GXAU,27970
|
|
163
164
|
sentry_sdk/profiler/utils.py,sha256=80MF0wiguKe47O-uWQfl-81G1caiVa8HgcFHWBzFpuM,6492
|
|
164
|
-
sentry_sdk-2.
|
|
165
|
-
sentry_sdk-2.
|
|
166
|
-
sentry_sdk-2.
|
|
167
|
-
sentry_sdk-2.
|
|
168
|
-
sentry_sdk-2.
|
|
169
|
-
sentry_sdk-2.
|
|
165
|
+
sentry_sdk-2.41.0.dist-info/licenses/LICENSE,sha256=KhQNZg9GKBL6KQvHQNBGMxJsXsRdhLebVp4Sew7t3Qs,1093
|
|
166
|
+
sentry_sdk-2.41.0.dist-info/METADATA,sha256=8cH1Csap1vj8PnY9-IRGoQuFSFqZUs4B_USzdXwoH4g,10433
|
|
167
|
+
sentry_sdk-2.41.0.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
|
168
|
+
sentry_sdk-2.41.0.dist-info/entry_points.txt,sha256=qacZEz40UspQZD1IukCXykx0JtImqGDOctS5KfOLTko,91
|
|
169
|
+
sentry_sdk-2.41.0.dist-info/top_level.txt,sha256=XrQz30XE9FKXSY_yGLrd9bsv2Rk390GTDJOSujYaMxI,11
|
|
170
|
+
sentry_sdk-2.41.0.dist-info/RECORD,,
|