sentry-sdk 3.0.0a2__py2.py3-none-any.whl → 3.0.0a4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sentry-sdk might be problematic. Click here for more details.
- sentry_sdk/__init__.py +4 -0
- sentry_sdk/_compat.py +5 -12
- sentry_sdk/_init_implementation.py +7 -7
- sentry_sdk/_log_batcher.py +17 -29
- sentry_sdk/_lru_cache.py +7 -9
- sentry_sdk/_queue.py +2 -4
- sentry_sdk/_types.py +9 -16
- sentry_sdk/_werkzeug.py +5 -7
- sentry_sdk/ai/monitoring.py +45 -33
- sentry_sdk/ai/utils.py +8 -5
- sentry_sdk/api.py +91 -87
- sentry_sdk/attachments.py +10 -12
- sentry_sdk/client.py +119 -159
- sentry_sdk/consts.py +432 -223
- sentry_sdk/crons/api.py +16 -17
- sentry_sdk/crons/decorator.py +25 -27
- sentry_sdk/debug.py +4 -6
- sentry_sdk/envelope.py +46 -112
- sentry_sdk/feature_flags.py +9 -15
- sentry_sdk/integrations/__init__.py +24 -19
- sentry_sdk/integrations/_asgi_common.py +16 -18
- sentry_sdk/integrations/_wsgi_common.py +22 -33
- sentry_sdk/integrations/aiohttp.py +33 -31
- sentry_sdk/integrations/anthropic.py +43 -38
- sentry_sdk/integrations/argv.py +3 -4
- sentry_sdk/integrations/ariadne.py +16 -18
- sentry_sdk/integrations/arq.py +20 -29
- sentry_sdk/integrations/asgi.py +63 -37
- sentry_sdk/integrations/asyncio.py +15 -17
- sentry_sdk/integrations/asyncpg.py +1 -1
- sentry_sdk/integrations/atexit.py +6 -10
- sentry_sdk/integrations/aws_lambda.py +26 -36
- sentry_sdk/integrations/beam.py +10 -18
- sentry_sdk/integrations/boto3.py +20 -18
- sentry_sdk/integrations/bottle.py +25 -34
- sentry_sdk/integrations/celery/__init__.py +40 -59
- sentry_sdk/integrations/celery/beat.py +22 -26
- sentry_sdk/integrations/celery/utils.py +15 -17
- sentry_sdk/integrations/chalice.py +8 -10
- sentry_sdk/integrations/clickhouse_driver.py +22 -32
- sentry_sdk/integrations/cloud_resource_context.py +9 -16
- sentry_sdk/integrations/cohere.py +19 -25
- sentry_sdk/integrations/dedupe.py +5 -8
- sentry_sdk/integrations/django/__init__.py +69 -74
- sentry_sdk/integrations/django/asgi.py +25 -33
- sentry_sdk/integrations/django/caching.py +24 -20
- sentry_sdk/integrations/django/middleware.py +18 -21
- sentry_sdk/integrations/django/signals_handlers.py +12 -11
- sentry_sdk/integrations/django/templates.py +21 -18
- sentry_sdk/integrations/django/transactions.py +16 -11
- sentry_sdk/integrations/django/views.py +8 -12
- sentry_sdk/integrations/dramatiq.py +21 -21
- sentry_sdk/integrations/excepthook.py +10 -10
- sentry_sdk/integrations/executing.py +3 -4
- sentry_sdk/integrations/falcon.py +27 -42
- sentry_sdk/integrations/fastapi.py +13 -16
- sentry_sdk/integrations/flask.py +31 -38
- sentry_sdk/integrations/gcp.py +13 -16
- sentry_sdk/integrations/gnu_backtrace.py +7 -20
- sentry_sdk/integrations/gql.py +16 -17
- sentry_sdk/integrations/graphene.py +14 -13
- sentry_sdk/integrations/grpc/__init__.py +3 -2
- sentry_sdk/integrations/grpc/aio/client.py +2 -2
- sentry_sdk/integrations/grpc/aio/server.py +15 -14
- sentry_sdk/integrations/grpc/client.py +21 -11
- sentry_sdk/integrations/grpc/consts.py +2 -0
- sentry_sdk/integrations/grpc/server.py +12 -8
- sentry_sdk/integrations/httpx.py +11 -14
- sentry_sdk/integrations/huey.py +14 -21
- sentry_sdk/integrations/huggingface_hub.py +17 -17
- sentry_sdk/integrations/langchain.py +204 -114
- sentry_sdk/integrations/launchdarkly.py +13 -10
- sentry_sdk/integrations/litestar.py +40 -38
- sentry_sdk/integrations/logging.py +29 -36
- sentry_sdk/integrations/loguru.py +16 -20
- sentry_sdk/integrations/modules.py +3 -4
- sentry_sdk/integrations/openai.py +421 -204
- sentry_sdk/integrations/openai_agents/__init__.py +49 -0
- sentry_sdk/integrations/openai_agents/consts.py +1 -0
- sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
- sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
- sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
- sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
- sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
- sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
- sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
- sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
- sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
- sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
- sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
- sentry_sdk/integrations/openai_agents/utils.py +153 -0
- sentry_sdk/integrations/openfeature.py +12 -8
- sentry_sdk/integrations/pure_eval.py +6 -10
- sentry_sdk/integrations/pymongo.py +14 -18
- sentry_sdk/integrations/pyramid.py +31 -36
- sentry_sdk/integrations/quart.py +23 -28
- sentry_sdk/integrations/ray.py +73 -64
- sentry_sdk/integrations/redis/__init__.py +7 -4
- sentry_sdk/integrations/redis/_async_common.py +18 -12
- sentry_sdk/integrations/redis/_sync_common.py +16 -15
- sentry_sdk/integrations/redis/modules/caches.py +17 -8
- sentry_sdk/integrations/redis/modules/queries.py +9 -8
- sentry_sdk/integrations/redis/rb.py +3 -2
- sentry_sdk/integrations/redis/redis.py +4 -4
- sentry_sdk/integrations/redis/redis_cluster.py +10 -8
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
- sentry_sdk/integrations/redis/utils.py +21 -22
- sentry_sdk/integrations/rq.py +13 -16
- sentry_sdk/integrations/rust_tracing.py +10 -7
- sentry_sdk/integrations/sanic.py +34 -46
- sentry_sdk/integrations/serverless.py +22 -27
- sentry_sdk/integrations/socket.py +29 -17
- sentry_sdk/integrations/spark/__init__.py +1 -0
- sentry_sdk/integrations/spark/spark_driver.py +45 -83
- sentry_sdk/integrations/spark/spark_worker.py +7 -11
- sentry_sdk/integrations/sqlalchemy.py +22 -19
- sentry_sdk/integrations/starlette.py +89 -93
- sentry_sdk/integrations/starlite.py +31 -37
- sentry_sdk/integrations/statsig.py +5 -4
- sentry_sdk/integrations/stdlib.py +32 -28
- sentry_sdk/integrations/strawberry.py +63 -50
- sentry_sdk/integrations/sys_exit.py +7 -11
- sentry_sdk/integrations/threading.py +13 -15
- sentry_sdk/integrations/tornado.py +28 -32
- sentry_sdk/integrations/trytond.py +4 -3
- sentry_sdk/integrations/typer.py +8 -6
- sentry_sdk/integrations/unleash.py +5 -4
- sentry_sdk/integrations/wsgi.py +47 -46
- sentry_sdk/logger.py +13 -9
- sentry_sdk/monitor.py +16 -28
- sentry_sdk/opentelemetry/consts.py +11 -4
- sentry_sdk/opentelemetry/contextvars_context.py +17 -15
- sentry_sdk/opentelemetry/propagator.py +38 -21
- sentry_sdk/opentelemetry/sampler.py +51 -34
- sentry_sdk/opentelemetry/scope.py +46 -37
- sentry_sdk/opentelemetry/span_processor.py +43 -59
- sentry_sdk/opentelemetry/tracing.py +32 -12
- sentry_sdk/opentelemetry/utils.py +180 -196
- sentry_sdk/profiler/continuous_profiler.py +108 -97
- sentry_sdk/profiler/transaction_profiler.py +70 -97
- sentry_sdk/profiler/utils.py +11 -15
- sentry_sdk/scope.py +251 -264
- sentry_sdk/scrubber.py +22 -26
- sentry_sdk/serializer.py +48 -65
- sentry_sdk/session.py +44 -61
- sentry_sdk/sessions.py +35 -49
- sentry_sdk/spotlight.py +15 -21
- sentry_sdk/tracing.py +118 -184
- sentry_sdk/tracing_utils.py +103 -123
- sentry_sdk/transport.py +131 -157
- sentry_sdk/utils.py +278 -309
- sentry_sdk/worker.py +16 -28
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/METADATA +1 -1
- sentry_sdk-3.0.0a4.dist-info/RECORD +168 -0
- sentry_sdk-3.0.0a2.dist-info/RECORD +0 -154
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/WHEEL +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/top_level.txt +0 -0
sentry_sdk/tracing_utils.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import contextlib
|
|
2
|
-
import decimal
|
|
3
3
|
import inspect
|
|
4
4
|
import os
|
|
5
5
|
import re
|
|
@@ -37,12 +37,8 @@ from sentry_sdk.utils import (
|
|
|
37
37
|
from typing import TYPE_CHECKING
|
|
38
38
|
|
|
39
39
|
if TYPE_CHECKING:
|
|
40
|
-
from typing import Any
|
|
41
|
-
from typing import Dict
|
|
42
|
-
from typing import Generator
|
|
43
|
-
from typing import Optional
|
|
44
|
-
from typing import Union
|
|
45
40
|
from types import FrameType
|
|
41
|
+
from typing import Any, Dict, Generator, Optional, Union
|
|
46
42
|
|
|
47
43
|
|
|
48
44
|
SENTRY_TRACE_REGEX = re.compile(
|
|
@@ -69,23 +65,19 @@ base64_stripped = (
|
|
|
69
65
|
class EnvironHeaders(Mapping): # type: ignore
|
|
70
66
|
def __init__(
|
|
71
67
|
self,
|
|
72
|
-
environ
|
|
73
|
-
prefix="HTTP_",
|
|
74
|
-
):
|
|
75
|
-
# type: (...) -> None
|
|
68
|
+
environ: Mapping[str, str],
|
|
69
|
+
prefix: str = "HTTP_",
|
|
70
|
+
) -> None:
|
|
76
71
|
self.environ = environ
|
|
77
72
|
self.prefix = prefix
|
|
78
73
|
|
|
79
|
-
def __getitem__(self, key):
|
|
80
|
-
# type: (str) -> Optional[Any]
|
|
74
|
+
def __getitem__(self, key: str) -> Optional[Any]:
|
|
81
75
|
return self.environ[self.prefix + key.replace("-", "_").upper()]
|
|
82
76
|
|
|
83
|
-
def __len__(self):
|
|
84
|
-
# type: () -> int
|
|
77
|
+
def __len__(self) -> int:
|
|
85
78
|
return sum(1 for _ in iter(self))
|
|
86
79
|
|
|
87
|
-
def __iter__(self):
|
|
88
|
-
# type: () -> Generator[str, None, None]
|
|
80
|
+
def __iter__(self) -> Generator[str, None, None]:
|
|
89
81
|
for k in self.environ:
|
|
90
82
|
if not isinstance(k, str):
|
|
91
83
|
continue
|
|
@@ -97,8 +89,7 @@ class EnvironHeaders(Mapping): # type: ignore
|
|
|
97
89
|
yield k[len(self.prefix) :]
|
|
98
90
|
|
|
99
91
|
|
|
100
|
-
def has_tracing_enabled(options):
|
|
101
|
-
# type: (Optional[Dict[str, Any]]) -> bool
|
|
92
|
+
def has_tracing_enabled(options: dict[str, Any]) -> bool:
|
|
102
93
|
"""
|
|
103
94
|
Returns True if either traces_sample_rate or traces_sampler is
|
|
104
95
|
defined.
|
|
@@ -114,16 +105,14 @@ def has_tracing_enabled(options):
|
|
|
114
105
|
|
|
115
106
|
@contextlib.contextmanager
|
|
116
107
|
def record_sql_queries(
|
|
117
|
-
cursor
|
|
118
|
-
query
|
|
119
|
-
params_list
|
|
120
|
-
paramstyle
|
|
121
|
-
executemany
|
|
122
|
-
record_cursor_repr=False,
|
|
123
|
-
span_origin
|
|
124
|
-
):
|
|
125
|
-
# type: (...) -> Generator[sentry_sdk.tracing.Span, None, None]
|
|
126
|
-
|
|
108
|
+
cursor: Any,
|
|
109
|
+
query: Any,
|
|
110
|
+
params_list: Any,
|
|
111
|
+
paramstyle: Optional[str],
|
|
112
|
+
executemany: bool,
|
|
113
|
+
record_cursor_repr: bool = False,
|
|
114
|
+
span_origin: Optional[str] = None,
|
|
115
|
+
) -> Generator[sentry_sdk.tracing.Span, None, None]:
|
|
127
116
|
# TODO: Bring back capturing of params by default
|
|
128
117
|
if sentry_sdk.get_client().options["_experiments"].get("record_sql_params", False):
|
|
129
118
|
if not params_list or params_list == [None]:
|
|
@@ -154,15 +143,14 @@ def record_sql_queries(
|
|
|
154
143
|
op=OP.DB,
|
|
155
144
|
name=query,
|
|
156
145
|
origin=span_origin,
|
|
157
|
-
|
|
146
|
+
only_as_child_span=True,
|
|
158
147
|
) as span:
|
|
159
148
|
for k, v in data.items():
|
|
160
149
|
span.set_attribute(k, v)
|
|
161
150
|
yield span
|
|
162
151
|
|
|
163
152
|
|
|
164
|
-
def _get_frame_module_abs_path(frame):
|
|
165
|
-
# type: (FrameType) -> Optional[str]
|
|
153
|
+
def _get_frame_module_abs_path(frame: FrameType) -> Optional[str]:
|
|
166
154
|
try:
|
|
167
155
|
return frame.f_code.co_filename
|
|
168
156
|
except Exception:
|
|
@@ -170,14 +158,13 @@ def _get_frame_module_abs_path(frame):
|
|
|
170
158
|
|
|
171
159
|
|
|
172
160
|
def _should_be_included(
|
|
173
|
-
is_sentry_sdk_frame
|
|
174
|
-
namespace
|
|
175
|
-
in_app_include
|
|
176
|
-
in_app_exclude
|
|
177
|
-
abs_path
|
|
178
|
-
project_root
|
|
179
|
-
):
|
|
180
|
-
# type: (...) -> bool
|
|
161
|
+
is_sentry_sdk_frame: bool,
|
|
162
|
+
namespace: Optional[str],
|
|
163
|
+
in_app_include: Optional[list[str]],
|
|
164
|
+
in_app_exclude: Optional[list[str]],
|
|
165
|
+
abs_path: Optional[str],
|
|
166
|
+
project_root: Optional[str],
|
|
167
|
+
) -> bool:
|
|
181
168
|
# in_app_include takes precedence over in_app_exclude
|
|
182
169
|
should_be_included = _module_in_list(namespace, in_app_include)
|
|
183
170
|
should_be_excluded = _is_external_source(abs_path) or _module_in_list(
|
|
@@ -189,8 +176,7 @@ def _should_be_included(
|
|
|
189
176
|
)
|
|
190
177
|
|
|
191
178
|
|
|
192
|
-
def add_query_source(span):
|
|
193
|
-
# type: (sentry_sdk.tracing.Span) -> None
|
|
179
|
+
def add_query_source(span: sentry_sdk.tracing.Span) -> None:
|
|
194
180
|
"""
|
|
195
181
|
Adds OTel compatible source code information to the span
|
|
196
182
|
"""
|
|
@@ -220,12 +206,12 @@ def add_query_source(span):
|
|
|
220
206
|
in_app_exclude = client.options.get("in_app_exclude")
|
|
221
207
|
|
|
222
208
|
# Find the correct frame
|
|
223
|
-
frame = sys._getframe()
|
|
209
|
+
frame: Optional[FrameType] = sys._getframe()
|
|
224
210
|
while frame is not None:
|
|
225
211
|
abs_path = _get_frame_module_abs_path(frame)
|
|
226
212
|
|
|
227
213
|
try:
|
|
228
|
-
namespace = frame.f_globals.get("__name__")
|
|
214
|
+
namespace: Optional[str] = frame.f_globals.get("__name__")
|
|
229
215
|
except Exception:
|
|
230
216
|
namespace = None
|
|
231
217
|
|
|
@@ -283,8 +269,9 @@ def add_query_source(span):
|
|
|
283
269
|
span.set_attribute(SPANDATA.CODE_FUNCTION, frame.f_code.co_name)
|
|
284
270
|
|
|
285
271
|
|
|
286
|
-
def extract_sentrytrace_data(
|
|
287
|
-
|
|
272
|
+
def extract_sentrytrace_data(
|
|
273
|
+
header: Optional[str],
|
|
274
|
+
) -> Optional[Dict[str, Union[str, bool, None]]]:
|
|
288
275
|
"""
|
|
289
276
|
Given a `sentry-trace` header string, return a dictionary of data.
|
|
290
277
|
"""
|
|
@@ -315,8 +302,7 @@ def extract_sentrytrace_data(header):
|
|
|
315
302
|
}
|
|
316
303
|
|
|
317
304
|
|
|
318
|
-
def _format_sql(cursor, sql):
|
|
319
|
-
# type: (Any, str) -> Optional[str]
|
|
305
|
+
def _format_sql(cursor: Any, sql: str) -> Optional[str]:
|
|
320
306
|
|
|
321
307
|
real_sql = None
|
|
322
308
|
|
|
@@ -350,13 +336,12 @@ class PropagationContext:
|
|
|
350
336
|
|
|
351
337
|
def __init__(
|
|
352
338
|
self,
|
|
353
|
-
trace_id
|
|
354
|
-
span_id
|
|
355
|
-
parent_span_id
|
|
356
|
-
parent_sampled
|
|
357
|
-
baggage
|
|
358
|
-
):
|
|
359
|
-
# type: (...) -> None
|
|
339
|
+
trace_id: Optional[str] = None,
|
|
340
|
+
span_id: Optional[str] = None,
|
|
341
|
+
parent_span_id: Optional[str] = None,
|
|
342
|
+
parent_sampled: Optional[bool] = None,
|
|
343
|
+
baggage: Optional[Baggage] = None,
|
|
344
|
+
) -> None:
|
|
360
345
|
self._trace_id = trace_id
|
|
361
346
|
"""The trace id of the Sentry trace."""
|
|
362
347
|
|
|
@@ -376,13 +361,13 @@ class PropagationContext:
|
|
|
376
361
|
"""Baggage object used for dynamic sampling decisions."""
|
|
377
362
|
|
|
378
363
|
@property
|
|
379
|
-
def dynamic_sampling_context(self):
|
|
380
|
-
# type: () -> Optional[Dict[str, str]]
|
|
364
|
+
def dynamic_sampling_context(self) -> Optional[Dict[str, str]]:
|
|
381
365
|
return self.baggage.dynamic_sampling_context() if self.baggage else None
|
|
382
366
|
|
|
383
367
|
@classmethod
|
|
384
|
-
def from_incoming_data(
|
|
385
|
-
|
|
368
|
+
def from_incoming_data(
|
|
369
|
+
cls, incoming_data: Dict[str, Any]
|
|
370
|
+
) -> Optional[PropagationContext]:
|
|
386
371
|
propagation_context = None
|
|
387
372
|
|
|
388
373
|
normalized_data = normalize_incoming_data(incoming_data)
|
|
@@ -405,8 +390,7 @@ class PropagationContext:
|
|
|
405
390
|
return propagation_context
|
|
406
391
|
|
|
407
392
|
@property
|
|
408
|
-
def trace_id(self):
|
|
409
|
-
# type: () -> str
|
|
393
|
+
def trace_id(self) -> str:
|
|
410
394
|
"""The trace id of the Sentry trace."""
|
|
411
395
|
if not self._trace_id:
|
|
412
396
|
self._trace_id = uuid.uuid4().hex
|
|
@@ -414,13 +398,11 @@ class PropagationContext:
|
|
|
414
398
|
return self._trace_id
|
|
415
399
|
|
|
416
400
|
@trace_id.setter
|
|
417
|
-
def trace_id(self, value):
|
|
418
|
-
# type: (str) -> None
|
|
401
|
+
def trace_id(self, value: str) -> None:
|
|
419
402
|
self._trace_id = value
|
|
420
403
|
|
|
421
404
|
@property
|
|
422
|
-
def span_id(self):
|
|
423
|
-
# type: () -> str
|
|
405
|
+
def span_id(self) -> str:
|
|
424
406
|
"""The span id of the currently executed span."""
|
|
425
407
|
if not self._span_id:
|
|
426
408
|
self._span_id = uuid.uuid4().hex[16:]
|
|
@@ -428,12 +410,10 @@ class PropagationContext:
|
|
|
428
410
|
return self._span_id
|
|
429
411
|
|
|
430
412
|
@span_id.setter
|
|
431
|
-
def span_id(self, value):
|
|
432
|
-
# type: (str) -> None
|
|
413
|
+
def span_id(self, value: str) -> None:
|
|
433
414
|
self._span_id = value
|
|
434
415
|
|
|
435
|
-
def to_traceparent(self):
|
|
436
|
-
# type: () -> str
|
|
416
|
+
def to_traceparent(self) -> str:
|
|
437
417
|
if self.parent_sampled is True:
|
|
438
418
|
sampled = "1"
|
|
439
419
|
elif self.parent_sampled is False:
|
|
@@ -447,8 +427,7 @@ class PropagationContext:
|
|
|
447
427
|
|
|
448
428
|
return traceparent
|
|
449
429
|
|
|
450
|
-
def update(self, other_dict):
|
|
451
|
-
# type: (Dict[str, Any]) -> None
|
|
430
|
+
def update(self, other_dict: Dict[str, Any]) -> None:
|
|
452
431
|
"""
|
|
453
432
|
Updates the PropagationContext with data from the given dictionary.
|
|
454
433
|
"""
|
|
@@ -458,8 +437,7 @@ class PropagationContext:
|
|
|
458
437
|
except AttributeError:
|
|
459
438
|
pass
|
|
460
439
|
|
|
461
|
-
def _fill_sample_rand(self):
|
|
462
|
-
# type: () -> None
|
|
440
|
+
def _fill_sample_rand(self) -> None:
|
|
463
441
|
"""
|
|
464
442
|
Ensure that there is a valid sample_rand value in the baggage.
|
|
465
443
|
|
|
@@ -522,16 +500,14 @@ class PropagationContext:
|
|
|
522
500
|
|
|
523
501
|
self.baggage.sentry_items["sample_rand"] = f"{sample_rand:.6f}" # noqa: E231
|
|
524
502
|
|
|
525
|
-
def _sample_rand(self):
|
|
526
|
-
# type: () -> Optional[str]
|
|
503
|
+
def _sample_rand(self) -> Optional[str]:
|
|
527
504
|
"""Convenience method to get the sample_rand value from the baggage."""
|
|
528
505
|
if self.baggage is None:
|
|
529
506
|
return None
|
|
530
507
|
|
|
531
508
|
return self.baggage.sentry_items.get("sample_rand")
|
|
532
509
|
|
|
533
|
-
def __repr__(self):
|
|
534
|
-
# type: (...) -> str
|
|
510
|
+
def __repr__(self) -> str:
|
|
535
511
|
return "<PropagationContext _trace_id={} _span_id={} parent_span_id={} parent_sampled={} baggage={} dynamic_sampling_context={}>".format(
|
|
536
512
|
self._trace_id,
|
|
537
513
|
self._span_id,
|
|
@@ -558,10 +534,10 @@ class Baggage:
|
|
|
558
534
|
|
|
559
535
|
def __init__(
|
|
560
536
|
self,
|
|
561
|
-
sentry_items
|
|
562
|
-
third_party_items="",
|
|
563
|
-
mutable=True,
|
|
564
|
-
):
|
|
537
|
+
sentry_items: Dict[str, str],
|
|
538
|
+
third_party_items: str = "",
|
|
539
|
+
mutable: bool = True,
|
|
540
|
+
) -> None:
|
|
565
541
|
self.sentry_items = sentry_items
|
|
566
542
|
self.third_party_items = third_party_items
|
|
567
543
|
self.mutable = mutable
|
|
@@ -569,9 +545,8 @@ class Baggage:
|
|
|
569
545
|
@classmethod
|
|
570
546
|
def from_incoming_header(
|
|
571
547
|
cls,
|
|
572
|
-
header
|
|
573
|
-
):
|
|
574
|
-
# type: (...) -> Baggage
|
|
548
|
+
header: Optional[str],
|
|
549
|
+
) -> Baggage:
|
|
575
550
|
"""
|
|
576
551
|
freeze if incoming header already has sentry baggage
|
|
577
552
|
"""
|
|
@@ -597,10 +572,8 @@ class Baggage:
|
|
|
597
572
|
return Baggage(sentry_items, third_party_items, mutable)
|
|
598
573
|
|
|
599
574
|
@classmethod
|
|
600
|
-
def from_options(cls, scope):
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
sentry_items = {} # type: Dict[str, str]
|
|
575
|
+
def from_options(cls, scope: sentry_sdk.scope.Scope) -> Optional[Baggage]:
|
|
576
|
+
sentry_items: Dict[str, str] = {}
|
|
604
577
|
third_party_items = ""
|
|
605
578
|
mutable = False
|
|
606
579
|
|
|
@@ -629,12 +602,10 @@ class Baggage:
|
|
|
629
602
|
|
|
630
603
|
return Baggage(sentry_items, third_party_items, mutable)
|
|
631
604
|
|
|
632
|
-
def freeze(self):
|
|
633
|
-
# type: () -> None
|
|
605
|
+
def freeze(self) -> None:
|
|
634
606
|
self.mutable = False
|
|
635
607
|
|
|
636
|
-
def dynamic_sampling_context(self):
|
|
637
|
-
# type: () -> Dict[str, str]
|
|
608
|
+
def dynamic_sampling_context(self) -> Dict[str, str]:
|
|
638
609
|
header = {}
|
|
639
610
|
|
|
640
611
|
for key, item in self.sentry_items.items():
|
|
@@ -642,8 +613,7 @@ class Baggage:
|
|
|
642
613
|
|
|
643
614
|
return header
|
|
644
615
|
|
|
645
|
-
def serialize(self, include_third_party=False):
|
|
646
|
-
# type: (bool) -> str
|
|
616
|
+
def serialize(self, include_third_party: bool = False) -> str:
|
|
647
617
|
items = []
|
|
648
618
|
|
|
649
619
|
for key, val in self.sentry_items.items():
|
|
@@ -657,8 +627,7 @@ class Baggage:
|
|
|
657
627
|
return ",".join(items)
|
|
658
628
|
|
|
659
629
|
@staticmethod
|
|
660
|
-
def strip_sentry_baggage(header):
|
|
661
|
-
# type: (str) -> str
|
|
630
|
+
def strip_sentry_baggage(header: str) -> str:
|
|
662
631
|
"""Remove Sentry baggage from the given header.
|
|
663
632
|
|
|
664
633
|
Given a Baggage header, return a new Baggage header with all Sentry baggage items removed.
|
|
@@ -671,13 +640,11 @@ class Baggage:
|
|
|
671
640
|
)
|
|
672
641
|
)
|
|
673
642
|
|
|
674
|
-
def __repr__(self):
|
|
675
|
-
# type: () -> str
|
|
643
|
+
def __repr__(self) -> str:
|
|
676
644
|
return f'<Baggage "{self.serialize(include_third_party=True)}", mutable={self.mutable}>'
|
|
677
645
|
|
|
678
646
|
|
|
679
|
-
def should_propagate_trace(client, url):
|
|
680
|
-
# type: (sentry_sdk.client.BaseClient, str) -> bool
|
|
647
|
+
def should_propagate_trace(client: sentry_sdk.client.BaseClient, url: str) -> bool:
|
|
681
648
|
"""
|
|
682
649
|
Returns True if url matches trace_propagation_targets configured in the given client. Otherwise, returns False.
|
|
683
650
|
"""
|
|
@@ -689,8 +656,22 @@ def should_propagate_trace(client, url):
|
|
|
689
656
|
return match_regex_list(url, trace_propagation_targets, substring_matching=True)
|
|
690
657
|
|
|
691
658
|
|
|
692
|
-
def
|
|
693
|
-
|
|
659
|
+
def _is_span_origin_excluded(origin: Optional[str]) -> bool:
|
|
660
|
+
"""
|
|
661
|
+
Check if spans with this origin should be ignored based on the `exclude_span_origins` option.
|
|
662
|
+
"""
|
|
663
|
+
if origin is None:
|
|
664
|
+
return False
|
|
665
|
+
|
|
666
|
+
client = sentry_sdk.get_client()
|
|
667
|
+
exclude_span_origins = client.options.get("exclude_span_origins")
|
|
668
|
+
if not exclude_span_origins:
|
|
669
|
+
return False
|
|
670
|
+
|
|
671
|
+
return match_regex_list(origin, exclude_span_origins, substring_matching=True)
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
def normalize_incoming_data(incoming_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
694
675
|
"""
|
|
695
676
|
Normalizes incoming data so the keys are all lowercase with dashes instead of underscores and stripped from known prefixes.
|
|
696
677
|
"""
|
|
@@ -705,8 +686,7 @@ def normalize_incoming_data(incoming_data):
|
|
|
705
686
|
return data
|
|
706
687
|
|
|
707
688
|
|
|
708
|
-
def start_child_span_decorator(func):
|
|
709
|
-
# type: (Any) -> Any
|
|
689
|
+
def start_child_span_decorator(func: Any) -> Any:
|
|
710
690
|
"""
|
|
711
691
|
Decorator to add child spans for functions.
|
|
712
692
|
|
|
@@ -716,9 +696,7 @@ def start_child_span_decorator(func):
|
|
|
716
696
|
if inspect.iscoroutinefunction(func):
|
|
717
697
|
|
|
718
698
|
@wraps(func)
|
|
719
|
-
async def func_with_tracing(*args, **kwargs):
|
|
720
|
-
# type: (*Any, **Any) -> Any
|
|
721
|
-
|
|
699
|
+
async def func_with_tracing(*args: Any, **kwargs: Any) -> Any:
|
|
722
700
|
span = get_current_span()
|
|
723
701
|
|
|
724
702
|
if span is None:
|
|
@@ -732,12 +710,14 @@ def start_child_span_decorator(func):
|
|
|
732
710
|
with sentry_sdk.start_span(
|
|
733
711
|
op=OP.FUNCTION,
|
|
734
712
|
name=qualname_from_function(func),
|
|
735
|
-
|
|
713
|
+
only_as_child_span=True,
|
|
736
714
|
):
|
|
737
715
|
return await func(*args, **kwargs)
|
|
738
716
|
|
|
739
717
|
try:
|
|
740
|
-
func_with_tracing.__signature__ = inspect.signature(
|
|
718
|
+
func_with_tracing.__signature__ = inspect.signature( # type: ignore[attr-defined]
|
|
719
|
+
func
|
|
720
|
+
)
|
|
741
721
|
except Exception:
|
|
742
722
|
pass
|
|
743
723
|
|
|
@@ -745,9 +725,7 @@ def start_child_span_decorator(func):
|
|
|
745
725
|
else:
|
|
746
726
|
|
|
747
727
|
@wraps(func)
|
|
748
|
-
def func_with_tracing(*args, **kwargs):
|
|
749
|
-
# type: (*Any, **Any) -> Any
|
|
750
|
-
|
|
728
|
+
def func_with_tracing(*args: Any, **kwargs: Any) -> Any:
|
|
751
729
|
span = get_current_span()
|
|
752
730
|
|
|
753
731
|
if span is None:
|
|
@@ -761,20 +739,23 @@ def start_child_span_decorator(func):
|
|
|
761
739
|
with sentry_sdk.start_span(
|
|
762
740
|
op=OP.FUNCTION,
|
|
763
741
|
name=qualname_from_function(func),
|
|
764
|
-
|
|
742
|
+
only_as_child_span=True,
|
|
765
743
|
):
|
|
766
744
|
return func(*args, **kwargs)
|
|
767
745
|
|
|
768
746
|
try:
|
|
769
|
-
func_with_tracing.__signature__ = inspect.signature(
|
|
747
|
+
func_with_tracing.__signature__ = inspect.signature( # type: ignore[attr-defined]
|
|
748
|
+
func
|
|
749
|
+
)
|
|
770
750
|
except Exception:
|
|
771
751
|
pass
|
|
772
752
|
|
|
773
753
|
return func_with_tracing
|
|
774
754
|
|
|
775
755
|
|
|
776
|
-
def get_current_span(
|
|
777
|
-
|
|
756
|
+
def get_current_span(
|
|
757
|
+
scope: Optional[sentry_sdk.scope.Scope] = None,
|
|
758
|
+
) -> Optional[sentry_sdk.tracing.Span]:
|
|
778
759
|
"""
|
|
779
760
|
Returns the currently active span if there is one running, otherwise `None`
|
|
780
761
|
"""
|
|
@@ -784,10 +765,9 @@ def get_current_span(scope=None):
|
|
|
784
765
|
|
|
785
766
|
|
|
786
767
|
def _generate_sample_rand(
|
|
787
|
-
trace_id
|
|
788
|
-
interval=(0.0, 1.0),
|
|
789
|
-
):
|
|
790
|
-
# type: (...) -> Optional[decimal.Decimal]
|
|
768
|
+
trace_id: Optional[str],
|
|
769
|
+
interval: tuple[float, float] = (0.0, 1.0),
|
|
770
|
+
) -> Decimal:
|
|
791
771
|
"""Generate a sample_rand value from a trace ID.
|
|
792
772
|
|
|
793
773
|
The generated value will be pseudorandomly chosen from the provided
|
|
@@ -817,8 +797,9 @@ def _generate_sample_rand(
|
|
|
817
797
|
)
|
|
818
798
|
|
|
819
799
|
|
|
820
|
-
def _sample_rand_range(
|
|
821
|
-
|
|
800
|
+
def _sample_rand_range(
|
|
801
|
+
parent_sampled: Optional[bool], sample_rate: Optional[float]
|
|
802
|
+
) -> tuple[float, float]:
|
|
822
803
|
"""
|
|
823
804
|
Compute the lower (inclusive) and upper (exclusive) bounds of the range of values
|
|
824
805
|
that a generated sample_rand value must fall into, given the parent_sampled and
|
|
@@ -832,8 +813,7 @@ def _sample_rand_range(parent_sampled, sample_rate):
|
|
|
832
813
|
return sample_rate, 1.0
|
|
833
814
|
|
|
834
815
|
|
|
835
|
-
def get_span_status_from_http_code(http_status_code):
|
|
836
|
-
# type: (int) -> str
|
|
816
|
+
def get_span_status_from_http_code(http_status_code: int) -> str:
|
|
837
817
|
"""
|
|
838
818
|
Returns the Sentry status corresponding to the given HTTP status code.
|
|
839
819
|
|