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/client.py
CHANGED
|
@@ -6,10 +6,9 @@ from collections.abc import Mapping
|
|
|
6
6
|
from datetime import datetime, timezone
|
|
7
7
|
from importlib import import_module
|
|
8
8
|
from typing import TYPE_CHECKING, List, Dict, cast, overload
|
|
9
|
-
import warnings
|
|
10
9
|
|
|
11
10
|
import sentry_sdk
|
|
12
|
-
from sentry_sdk._compat import
|
|
11
|
+
from sentry_sdk._compat import check_uwsgi_thread_support
|
|
13
12
|
from sentry_sdk.utils import (
|
|
14
13
|
AnnotatedValue,
|
|
15
14
|
ContextVar,
|
|
@@ -21,7 +20,6 @@ from sentry_sdk.utils import (
|
|
|
21
20
|
get_type_name,
|
|
22
21
|
get_default_release,
|
|
23
22
|
handle_in_app,
|
|
24
|
-
is_gevent,
|
|
25
23
|
logger,
|
|
26
24
|
)
|
|
27
25
|
from sentry_sdk.serializer import serialize
|
|
@@ -31,14 +29,14 @@ from sentry_sdk.consts import (
|
|
|
31
29
|
SPANDATA,
|
|
32
30
|
DEFAULT_MAX_VALUE_LENGTH,
|
|
33
31
|
DEFAULT_OPTIONS,
|
|
34
|
-
INSTRUMENTER,
|
|
35
32
|
VERSION,
|
|
36
33
|
ClientConstructor,
|
|
37
34
|
)
|
|
38
|
-
from sentry_sdk.integrations import
|
|
35
|
+
from sentry_sdk.integrations import setup_integrations
|
|
39
36
|
from sentry_sdk.integrations.dedupe import DedupeIntegration
|
|
40
37
|
from sentry_sdk.sessions import SessionFlusher
|
|
41
38
|
from sentry_sdk.envelope import Envelope
|
|
39
|
+
|
|
42
40
|
from sentry_sdk.profiler.continuous_profiler import setup_continuous_profiler
|
|
43
41
|
from sentry_sdk.profiler.transaction_profiler import (
|
|
44
42
|
has_profiling_enabled,
|
|
@@ -60,7 +58,6 @@ if TYPE_CHECKING:
|
|
|
60
58
|
|
|
61
59
|
from sentry_sdk._types import Event, Hint, SDKInfo, Log
|
|
62
60
|
from sentry_sdk.integrations import Integration
|
|
63
|
-
from sentry_sdk.metrics import MetricsAggregator
|
|
64
61
|
from sentry_sdk.scope import Scope
|
|
65
62
|
from sentry_sdk.session import Session
|
|
66
63
|
from sentry_sdk.spotlight import SpotlightClient
|
|
@@ -116,9 +113,6 @@ def _get_options(*args, **kwargs):
|
|
|
116
113
|
if rv["server_name"] is None and hasattr(socket, "gethostname"):
|
|
117
114
|
rv["server_name"] = socket.gethostname()
|
|
118
115
|
|
|
119
|
-
if rv["instrumenter"] is None:
|
|
120
|
-
rv["instrumenter"] = INSTRUMENTER.SENTRY
|
|
121
|
-
|
|
122
116
|
if rv["project_root"] is None:
|
|
123
117
|
try:
|
|
124
118
|
project_root = os.getcwd()
|
|
@@ -127,9 +121,6 @@ def _get_options(*args, **kwargs):
|
|
|
127
121
|
|
|
128
122
|
rv["project_root"] = project_root
|
|
129
123
|
|
|
130
|
-
if rv["enable_tracing"] is True and rv["traces_sample_rate"] is None:
|
|
131
|
-
rv["traces_sample_rate"] = 1.0
|
|
132
|
-
|
|
133
124
|
if rv["event_scrubber"] is None:
|
|
134
125
|
rv["event_scrubber"] = EventScrubber(
|
|
135
126
|
send_default_pii=(
|
|
@@ -148,24 +139,9 @@ def _get_options(*args, **kwargs):
|
|
|
148
139
|
env_to_bool(os.environ.get("SENTRY_KEEP_ALIVE"), strict=True) or False
|
|
149
140
|
)
|
|
150
141
|
|
|
151
|
-
if rv["enable_tracing"] is not None:
|
|
152
|
-
warnings.warn(
|
|
153
|
-
"The `enable_tracing` parameter is deprecated. Please use `traces_sample_rate` instead.",
|
|
154
|
-
DeprecationWarning,
|
|
155
|
-
stacklevel=2,
|
|
156
|
-
)
|
|
157
|
-
|
|
158
142
|
return rv
|
|
159
143
|
|
|
160
144
|
|
|
161
|
-
try:
|
|
162
|
-
# Python 3.6+
|
|
163
|
-
module_not_found_error = ModuleNotFoundError
|
|
164
|
-
except Exception:
|
|
165
|
-
# Older Python versions
|
|
166
|
-
module_not_found_error = ImportError # type: ignore
|
|
167
|
-
|
|
168
|
-
|
|
169
145
|
class BaseClient:
|
|
170
146
|
"""
|
|
171
147
|
.. versionadded:: 2.0.0
|
|
@@ -183,7 +159,6 @@ class BaseClient:
|
|
|
183
159
|
|
|
184
160
|
self.transport = None # type: Optional[Transport]
|
|
185
161
|
self.monitor = None # type: Optional[Monitor]
|
|
186
|
-
self.metrics_aggregator = None # type: Optional[MetricsAggregator]
|
|
187
162
|
self.log_batcher = None # type: Optional[LogBatcher]
|
|
188
163
|
|
|
189
164
|
def __getstate__(self, *args, **kwargs):
|
|
@@ -309,7 +284,7 @@ class _Client(BaseClient):
|
|
|
309
284
|
function_obj = getattr(module_obj, function_name)
|
|
310
285
|
setattr(module_obj, function_name, trace(function_obj))
|
|
311
286
|
logger.debug("Enabled tracing for %s", function_qualname)
|
|
312
|
-
except
|
|
287
|
+
except ModuleNotFoundError:
|
|
313
288
|
try:
|
|
314
289
|
# Try to import a class
|
|
315
290
|
# ex: "mymodule.submodule.MyClassName.member_function"
|
|
@@ -362,26 +337,7 @@ class _Client(BaseClient):
|
|
|
362
337
|
|
|
363
338
|
self.session_flusher = SessionFlusher(capture_func=_capture_envelope)
|
|
364
339
|
|
|
365
|
-
self.metrics_aggregator = None # type: Optional[MetricsAggregator]
|
|
366
340
|
experiments = self.options.get("_experiments", {})
|
|
367
|
-
if experiments.get("enable_metrics", True):
|
|
368
|
-
# Context vars are not working correctly on Python <=3.6
|
|
369
|
-
# with gevent.
|
|
370
|
-
metrics_supported = not is_gevent() or PY37
|
|
371
|
-
if metrics_supported:
|
|
372
|
-
from sentry_sdk.metrics import MetricsAggregator
|
|
373
|
-
|
|
374
|
-
self.metrics_aggregator = MetricsAggregator(
|
|
375
|
-
capture_func=_capture_envelope,
|
|
376
|
-
enable_code_locations=bool(
|
|
377
|
-
experiments.get("metric_code_locations", True)
|
|
378
|
-
),
|
|
379
|
-
)
|
|
380
|
-
else:
|
|
381
|
-
logger.info(
|
|
382
|
-
"Metrics not supported on Python 3.6 and lower with gevent."
|
|
383
|
-
)
|
|
384
|
-
|
|
385
341
|
self.log_batcher = None
|
|
386
342
|
if experiments.get("enable_logs", False):
|
|
387
343
|
from sentry_sdk._log_batcher import LogBatcher
|
|
@@ -396,19 +352,6 @@ class _Client(BaseClient):
|
|
|
396
352
|
)
|
|
397
353
|
)
|
|
398
354
|
|
|
399
|
-
if self.options["_experiments"].get("otel_powered_performance", False):
|
|
400
|
-
logger.debug(
|
|
401
|
-
"[OTel] Enabling experimental OTel-powered performance monitoring."
|
|
402
|
-
)
|
|
403
|
-
self.options["instrumenter"] = INSTRUMENTER.OTEL
|
|
404
|
-
if (
|
|
405
|
-
"sentry_sdk.integrations.opentelemetry.integration.OpenTelemetryIntegration"
|
|
406
|
-
not in _DEFAULT_INTEGRATIONS
|
|
407
|
-
):
|
|
408
|
-
_DEFAULT_INTEGRATIONS.append(
|
|
409
|
-
"sentry_sdk.integrations.opentelemetry.integration.OpenTelemetryIntegration",
|
|
410
|
-
)
|
|
411
|
-
|
|
412
355
|
self.integrations = setup_integrations(
|
|
413
356
|
self.options["integrations"],
|
|
414
357
|
with_defaults=self.options["default_integrations"],
|
|
@@ -456,6 +399,15 @@ class _Client(BaseClient):
|
|
|
456
399
|
except Exception as e:
|
|
457
400
|
logger.debug("Can not set up continuous profiler. (%s)", e)
|
|
458
401
|
|
|
402
|
+
from sentry_sdk.opentelemetry.tracing import (
|
|
403
|
+
patch_readable_span,
|
|
404
|
+
setup_sentry_tracing,
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
patch_readable_span()
|
|
408
|
+
setup_sentry_tracing()
|
|
409
|
+
|
|
410
|
+
logger.debug("[Tracing] Finished setting up OpenTelemetry")
|
|
459
411
|
finally:
|
|
460
412
|
_client_init_debug.set(old_debug)
|
|
461
413
|
|
|
@@ -463,7 +415,6 @@ class _Client(BaseClient):
|
|
|
463
415
|
|
|
464
416
|
if (
|
|
465
417
|
self.monitor
|
|
466
|
-
or self.metrics_aggregator
|
|
467
418
|
or self.log_batcher
|
|
468
419
|
or has_profiling_enabled(self.options)
|
|
469
420
|
or isinstance(self.transport, BaseHttpTransport)
|
|
@@ -530,7 +481,7 @@ class _Client(BaseClient):
|
|
|
530
481
|
)
|
|
531
482
|
return None
|
|
532
483
|
|
|
533
|
-
event = event_
|
|
484
|
+
event = event_ # type: Optional[Event] # type: ignore[no-redef]
|
|
534
485
|
spans_delta = spans_before - len(
|
|
535
486
|
cast(List[Dict[str, object]], event.get("spans", []))
|
|
536
487
|
)
|
|
@@ -627,7 +578,7 @@ class _Client(BaseClient):
|
|
|
627
578
|
and event is not None
|
|
628
579
|
and event.get("type") != "transaction"
|
|
629
580
|
):
|
|
630
|
-
new_event = None
|
|
581
|
+
new_event = None # type: Optional[Event]
|
|
631
582
|
with capture_internal_exceptions():
|
|
632
583
|
new_event = before_send(event, hint or {})
|
|
633
584
|
if new_event is None:
|
|
@@ -644,7 +595,7 @@ class _Client(BaseClient):
|
|
|
644
595
|
if event.get("exception"):
|
|
645
596
|
DedupeIntegration.reset_last_seen()
|
|
646
597
|
|
|
647
|
-
event = new_event
|
|
598
|
+
event = new_event # type: Optional[Event] # type: ignore[no-redef]
|
|
648
599
|
|
|
649
600
|
before_send_transaction = self.options["before_send_transaction"]
|
|
650
601
|
if (
|
|
@@ -668,13 +619,15 @@ class _Client(BaseClient):
|
|
|
668
619
|
quantity=spans_before + 1, # +1 for the transaction itself
|
|
669
620
|
)
|
|
670
621
|
else:
|
|
671
|
-
spans_delta = spans_before - len(
|
|
622
|
+
spans_delta = spans_before - len(
|
|
623
|
+
cast(List[Dict[str, object]], new_event.get("spans", []))
|
|
624
|
+
)
|
|
672
625
|
if spans_delta > 0 and self.transport is not None:
|
|
673
626
|
self.transport.record_lost_event(
|
|
674
627
|
reason="before_send", data_category="span", quantity=spans_delta
|
|
675
628
|
)
|
|
676
629
|
|
|
677
|
-
event = new_event
|
|
630
|
+
event = new_event # type: Optional[Event] # type: ignore[no-redef]
|
|
678
631
|
|
|
679
632
|
return event
|
|
680
633
|
|
|
@@ -923,7 +876,7 @@ class _Client(BaseClient):
|
|
|
923
876
|
log["attributes"]["sentry.trace.parent_span_id"] = span.span_id
|
|
924
877
|
|
|
925
878
|
if log.get("trace_id") is None:
|
|
926
|
-
transaction = current_scope.
|
|
879
|
+
transaction = current_scope.root_span
|
|
927
880
|
propagation_context = isolation_scope.get_active_propagation_context()
|
|
928
881
|
if transaction is not None:
|
|
929
882
|
log["trace_id"] = transaction.trace_id
|
|
@@ -1010,13 +963,15 @@ class _Client(BaseClient):
|
|
|
1010
963
|
"""
|
|
1011
964
|
if self.transport is not None:
|
|
1012
965
|
self.flush(timeout=timeout, callback=callback)
|
|
966
|
+
|
|
1013
967
|
self.session_flusher.kill()
|
|
1014
|
-
|
|
1015
|
-
self.metrics_aggregator.kill()
|
|
968
|
+
|
|
1016
969
|
if self.log_batcher is not None:
|
|
1017
970
|
self.log_batcher.kill()
|
|
971
|
+
|
|
1018
972
|
if self.monitor:
|
|
1019
973
|
self.monitor.kill()
|
|
974
|
+
|
|
1020
975
|
self.transport.kill()
|
|
1021
976
|
self.transport = None
|
|
1022
977
|
|
|
@@ -1037,10 +992,10 @@ class _Client(BaseClient):
|
|
|
1037
992
|
if timeout is None:
|
|
1038
993
|
timeout = self.options["shutdown_timeout"]
|
|
1039
994
|
self.session_flusher.flush()
|
|
1040
|
-
|
|
1041
|
-
self.metrics_aggregator.flush()
|
|
995
|
+
|
|
1042
996
|
if self.log_batcher is not None:
|
|
1043
997
|
self.log_batcher.flush()
|
|
998
|
+
|
|
1044
999
|
self.transport.flush(timeout=timeout, callback=callback)
|
|
1045
1000
|
|
|
1046
1001
|
def __enter__(self):
|
sentry_sdk/consts.py
CHANGED
|
@@ -47,12 +47,9 @@ if TYPE_CHECKING:
|
|
|
47
47
|
EventProcessor,
|
|
48
48
|
Hint,
|
|
49
49
|
Log,
|
|
50
|
-
MeasurementUnit,
|
|
51
50
|
ProfilerMode,
|
|
52
51
|
TracesSampler,
|
|
53
52
|
TransactionProcessor,
|
|
54
|
-
MetricTags,
|
|
55
|
-
MetricValue,
|
|
56
53
|
)
|
|
57
54
|
|
|
58
55
|
# Experiments are feature flags to enable and disable certain unstable SDK
|
|
@@ -73,11 +70,6 @@ if TYPE_CHECKING:
|
|
|
73
70
|
"transport_compression_algo": Optional[CompressionAlgo],
|
|
74
71
|
"transport_num_pools": Optional[int],
|
|
75
72
|
"transport_http2": Optional[bool],
|
|
76
|
-
"enable_metrics": Optional[bool],
|
|
77
|
-
"before_emit_metric": Optional[
|
|
78
|
-
Callable[[str, MetricValue, MeasurementUnit, MetricTags], bool]
|
|
79
|
-
],
|
|
80
|
-
"metric_code_locations": Optional[bool],
|
|
81
73
|
"enable_logs": Optional[bool],
|
|
82
74
|
"before_send_log": Optional[Callable[[Log, Hint], Optional[Log]]],
|
|
83
75
|
},
|
|
@@ -97,11 +89,6 @@ FALSE_VALUES = [
|
|
|
97
89
|
]
|
|
98
90
|
|
|
99
91
|
|
|
100
|
-
class INSTRUMENTER:
|
|
101
|
-
SENTRY = "sentry"
|
|
102
|
-
OTEL = "otel"
|
|
103
|
-
|
|
104
|
-
|
|
105
92
|
class SPANDATA:
|
|
106
93
|
"""
|
|
107
94
|
Additional information describing the type of the span.
|
|
@@ -175,7 +162,7 @@ class SPANDATA:
|
|
|
175
162
|
|
|
176
163
|
AI_TOOL_CALLS = "ai.tool_calls"
|
|
177
164
|
"""
|
|
178
|
-
For an AI model call, the function that was called.
|
|
165
|
+
For an AI model call, the function that was called.
|
|
179
166
|
"""
|
|
180
167
|
|
|
181
168
|
AI_TOOLS = "ai.tools"
|
|
@@ -265,6 +252,24 @@ class SPANDATA:
|
|
|
265
252
|
Example: "qa-pipeline"
|
|
266
253
|
"""
|
|
267
254
|
|
|
255
|
+
AI_PROMPT_TOKENS_USED = "ai.prompt_tokens.used"
|
|
256
|
+
"""
|
|
257
|
+
The number of input prompt tokens used by the model.
|
|
258
|
+
Example: 10
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
AI_COMPLETION_TOKENS_USED = "ai.completion_tokens.used"
|
|
262
|
+
"""
|
|
263
|
+
The number of output completion tokens used by the model.
|
|
264
|
+
Example: 10
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
AI_TOTAL_TOKENS_USED = "ai.total_tokens.used"
|
|
268
|
+
"""
|
|
269
|
+
The total number of tokens (input + output) used by the request to the model.
|
|
270
|
+
Example: 20
|
|
271
|
+
"""
|
|
272
|
+
|
|
268
273
|
AI_TEXTS = "ai.texts"
|
|
269
274
|
"""
|
|
270
275
|
Raw text inputs provided to the model.
|
|
@@ -551,6 +556,46 @@ class OP:
|
|
|
551
556
|
SOCKET_DNS = "socket.dns"
|
|
552
557
|
|
|
553
558
|
|
|
559
|
+
BAGGAGE_HEADER_NAME = "baggage"
|
|
560
|
+
SENTRY_TRACE_HEADER_NAME = "sentry-trace"
|
|
561
|
+
|
|
562
|
+
DEFAULT_SPAN_ORIGIN = "manual"
|
|
563
|
+
DEFAULT_SPAN_NAME = "<unlabeled span>"
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
# Transaction source
|
|
567
|
+
# see https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations
|
|
568
|
+
class TransactionSource(str, Enum):
|
|
569
|
+
COMPONENT = "component"
|
|
570
|
+
CUSTOM = "custom"
|
|
571
|
+
ROUTE = "route"
|
|
572
|
+
TASK = "task"
|
|
573
|
+
URL = "url"
|
|
574
|
+
VIEW = "view"
|
|
575
|
+
|
|
576
|
+
def __str__(self):
|
|
577
|
+
# type: () -> str
|
|
578
|
+
return self.value
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
# These are typically high cardinality and the server hates them
|
|
582
|
+
LOW_QUALITY_TRANSACTION_SOURCES = [
|
|
583
|
+
TransactionSource.URL,
|
|
584
|
+
]
|
|
585
|
+
|
|
586
|
+
SOURCE_FOR_STYLE = {
|
|
587
|
+
"endpoint": TransactionSource.COMPONENT,
|
|
588
|
+
"function_name": TransactionSource.COMPONENT,
|
|
589
|
+
"handler_name": TransactionSource.COMPONENT,
|
|
590
|
+
"method_and_path_pattern": TransactionSource.ROUTE,
|
|
591
|
+
"path": TransactionSource.URL,
|
|
592
|
+
"route_name": TransactionSource.COMPONENT,
|
|
593
|
+
"route_pattern": TransactionSource.ROUTE,
|
|
594
|
+
"uri_template": TransactionSource.ROUTE,
|
|
595
|
+
"url": TransactionSource.ROUTE,
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
|
|
554
599
|
# This type exists to trick mypy and PyCharm into thinking `init` and `Client`
|
|
555
600
|
# take these arguments (even though they take opaque **kwargs)
|
|
556
601
|
class ClientConstructor:
|
|
@@ -584,7 +629,6 @@ class ClientConstructor:
|
|
|
584
629
|
debug=None, # type: Optional[bool]
|
|
585
630
|
attach_stacktrace=False, # type: bool
|
|
586
631
|
ca_certs=None, # type: Optional[str]
|
|
587
|
-
propagate_traces=True, # type: bool
|
|
588
632
|
traces_sample_rate=None, # type: Optional[float]
|
|
589
633
|
traces_sampler=None, # type: Optional[TracesSampler]
|
|
590
634
|
profiles_sample_rate=None, # type: Optional[float]
|
|
@@ -598,10 +642,8 @@ class ClientConstructor:
|
|
|
598
642
|
send_client_reports=True, # type: bool
|
|
599
643
|
_experiments={}, # type: Experiments # noqa: B006
|
|
600
644
|
proxy_headers=None, # type: Optional[Dict[str, str]]
|
|
601
|
-
instrumenter=INSTRUMENTER.SENTRY, # type: Optional[str]
|
|
602
645
|
before_send_transaction=None, # type: Optional[TransactionProcessor]
|
|
603
646
|
project_root=None, # type: Optional[str]
|
|
604
|
-
enable_tracing=None, # type: Optional[bool]
|
|
605
647
|
include_local_variables=True, # type: Optional[bool]
|
|
606
648
|
include_source_context=True, # type: Optional[bool]
|
|
607
649
|
trace_propagation_targets=[ # noqa: B006
|
|
@@ -990,11 +1032,6 @@ class ClientConstructor:
|
|
|
990
1032
|
|
|
991
1033
|
:param profile_session_sample_rate:
|
|
992
1034
|
|
|
993
|
-
|
|
994
|
-
:param enable_tracing:
|
|
995
|
-
|
|
996
|
-
:param propagate_traces:
|
|
997
|
-
|
|
998
1035
|
:param auto_session_tracking:
|
|
999
1036
|
|
|
1000
1037
|
:param spotlight:
|
|
@@ -1026,4 +1063,4 @@ DEFAULT_OPTIONS = _get_default_options()
|
|
|
1026
1063
|
del _get_default_options
|
|
1027
1064
|
|
|
1028
1065
|
|
|
1029
|
-
VERSION = "
|
|
1066
|
+
VERSION = "3.0.0a2"
|
sentry_sdk/debug.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
import logging
|
|
3
|
-
import warnings
|
|
4
3
|
|
|
5
4
|
from sentry_sdk import get_client
|
|
6
5
|
from sentry_sdk.client import _client_init_debug
|
|
@@ -30,12 +29,3 @@ def configure_logger():
|
|
|
30
29
|
logger.addHandler(_handler)
|
|
31
30
|
logger.setLevel(logging.DEBUG)
|
|
32
31
|
logger.addFilter(_DebugFilter())
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def configure_debug_hub():
|
|
36
|
-
# type: () -> None
|
|
37
|
-
warnings.warn(
|
|
38
|
-
"configure_debug_hub is deprecated. Please remove calls to it, as it is a no-op.",
|
|
39
|
-
DeprecationWarning,
|
|
40
|
-
stacklevel=2,
|
|
41
|
-
)
|
sentry_sdk/envelope.py
CHANGED
|
@@ -280,8 +280,6 @@ class Item:
|
|
|
280
280
|
return "profile"
|
|
281
281
|
elif ty == "profile_chunk":
|
|
282
282
|
return "profile_chunk"
|
|
283
|
-
elif ty == "statsd":
|
|
284
|
-
return "metric_bucket"
|
|
285
283
|
elif ty == "check_in":
|
|
286
284
|
return "monitor"
|
|
287
285
|
else:
|
|
@@ -341,7 +339,7 @@ class Item:
|
|
|
341
339
|
# if no length was specified we need to read up to the end of line
|
|
342
340
|
# and remove it (if it is present, i.e. not the very last char in an eof terminated envelope)
|
|
343
341
|
payload = f.readline().rstrip(b"\n")
|
|
344
|
-
if headers.get("type") in ("event", "transaction"
|
|
342
|
+
if headers.get("type") in ("event", "transaction"):
|
|
345
343
|
rv = cls(headers=headers, payload=PayloadRef(json=parse_json(payload)))
|
|
346
344
|
else:
|
|
347
345
|
rv = cls(headers=headers, payload=payload)
|
sentry_sdk/feature_flags.py
CHANGED
|
@@ -131,10 +131,11 @@ _MIN_VERSIONS = {
|
|
|
131
131
|
"celery": (4, 4, 7),
|
|
132
132
|
"chalice": (1, 16, 0),
|
|
133
133
|
"clickhouse_driver": (0, 2, 0),
|
|
134
|
+
"common": (1, 4, 0), # opentelemetry-sdk
|
|
134
135
|
"cohere": (5, 4, 0),
|
|
135
|
-
"django": (
|
|
136
|
+
"django": (2, 0),
|
|
136
137
|
"dramatiq": (1, 9),
|
|
137
|
-
"falcon": (
|
|
138
|
+
"falcon": (3, 0),
|
|
138
139
|
"fastapi": (0, 79, 0),
|
|
139
140
|
"flask": (1, 1, 4),
|
|
140
141
|
"gql": (3, 4, 1),
|
|
@@ -157,6 +158,7 @@ _MIN_VERSIONS = {
|
|
|
157
158
|
"statsig": (0, 55, 3),
|
|
158
159
|
"strawberry": (0, 209, 5),
|
|
159
160
|
"tornado": (6, 0),
|
|
161
|
+
"trytond": (5, 0),
|
|
160
162
|
"typer": (0, 15),
|
|
161
163
|
"unleash": (6, 0, 1),
|
|
162
164
|
}
|
|
@@ -3,7 +3,7 @@ import urllib
|
|
|
3
3
|
from sentry_sdk.scope import should_send_default_pii
|
|
4
4
|
from sentry_sdk.integrations._wsgi_common import _filter_headers
|
|
5
5
|
|
|
6
|
-
from typing import TYPE_CHECKING
|
|
6
|
+
from typing import TYPE_CHECKING, cast
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from typing import Any
|
|
@@ -21,7 +21,7 @@ def _get_headers(asgi_scope):
|
|
|
21
21
|
Extract headers from the ASGI scope, in the format that the Sentry protocol expects.
|
|
22
22
|
"""
|
|
23
23
|
headers = {} # type: Dict[str, str]
|
|
24
|
-
for raw_key, raw_value in asgi_scope
|
|
24
|
+
for raw_key, raw_value in asgi_scope.get("headers", {}):
|
|
25
25
|
key = raw_key.decode("latin-1")
|
|
26
26
|
value = raw_value.decode("latin-1")
|
|
27
27
|
if key in headers:
|
|
@@ -32,13 +32,12 @@ def _get_headers(asgi_scope):
|
|
|
32
32
|
return headers
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def _get_url(asgi_scope, default_scheme, host):
|
|
36
|
-
# type: (Dict[str, Any], Literal["ws", "http"], Optional[Union[AnnotatedValue, str]]) -> str
|
|
35
|
+
def _get_url(asgi_scope, default_scheme=None, host=None):
|
|
36
|
+
# type: (Dict[str, Any], Optional[Literal["ws", "http"]], Optional[Union[AnnotatedValue, str]]) -> str
|
|
37
37
|
"""
|
|
38
38
|
Extract URL from the ASGI scope, without also including the querystring.
|
|
39
39
|
"""
|
|
40
|
-
scheme = asgi_scope.get("scheme", default_scheme)
|
|
41
|
-
|
|
40
|
+
scheme = cast(str, asgi_scope.get("scheme", default_scheme))
|
|
42
41
|
server = asgi_scope.get("server", None)
|
|
43
42
|
path = asgi_scope.get("root_path", "") + asgi_scope.get("path", "")
|
|
44
43
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
from contextlib import contextmanager
|
|
2
1
|
import json
|
|
3
2
|
from copy import deepcopy
|
|
4
3
|
|
|
5
4
|
import sentry_sdk
|
|
6
5
|
from sentry_sdk.scope import should_send_default_pii
|
|
7
|
-
from sentry_sdk.utils import AnnotatedValue,
|
|
6
|
+
from sentry_sdk.utils import AnnotatedValue, SENSITIVE_DATA_SUBSTITUTE
|
|
8
7
|
|
|
9
8
|
try:
|
|
10
9
|
from django.http.request import RawPostDataException
|
|
@@ -16,12 +15,11 @@ from typing import TYPE_CHECKING
|
|
|
16
15
|
if TYPE_CHECKING:
|
|
17
16
|
from typing import Any
|
|
18
17
|
from typing import Dict
|
|
19
|
-
from typing import Iterator
|
|
20
18
|
from typing import Mapping
|
|
21
19
|
from typing import MutableMapping
|
|
22
20
|
from typing import Optional
|
|
23
21
|
from typing import Union
|
|
24
|
-
from sentry_sdk._types import Event
|
|
22
|
+
from sentry_sdk._types import Event
|
|
25
23
|
|
|
26
24
|
|
|
27
25
|
SENSITIVE_ENV_KEYS = (
|
|
@@ -52,13 +50,6 @@ DEFAULT_HTTP_METHODS_TO_CAPTURE = (
|
|
|
52
50
|
)
|
|
53
51
|
|
|
54
52
|
|
|
55
|
-
# This noop context manager can be replaced with "from contextlib import nullcontext" when we drop Python 3.6 support
|
|
56
|
-
@contextmanager
|
|
57
|
-
def nullcontext():
|
|
58
|
-
# type: () -> Iterator[None]
|
|
59
|
-
yield
|
|
60
|
-
|
|
61
|
-
|
|
62
53
|
def request_body_within_bounds(client, content_length):
|
|
63
54
|
# type: (Optional[sentry_sdk.client.BaseClient], int) -> bool
|
|
64
55
|
if client is None:
|
|
@@ -237,35 +228,15 @@ def _filter_headers(headers):
|
|
|
237
228
|
}
|
|
238
229
|
|
|
239
230
|
|
|
240
|
-
def
|
|
241
|
-
# type: (
|
|
242
|
-
|
|
243
|
-
if isinstance(target, int):
|
|
244
|
-
if code == target:
|
|
245
|
-
return True
|
|
246
|
-
continue
|
|
247
|
-
|
|
248
|
-
try:
|
|
249
|
-
if code in target:
|
|
250
|
-
return True
|
|
251
|
-
except TypeError:
|
|
252
|
-
logger.warning(
|
|
253
|
-
"failed_request_status_codes has to be a list of integers or containers"
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
return False
|
|
257
|
-
|
|
231
|
+
def _request_headers_to_span_attributes(headers):
|
|
232
|
+
# type: (dict[str, str]) -> dict[str, str]
|
|
233
|
+
attributes = {}
|
|
258
234
|
|
|
259
|
-
|
|
260
|
-
"""
|
|
261
|
-
Wrapper to make it possible to use list[HttpStatusCodeRange] as a Container[int].
|
|
262
|
-
Used for backwards compatibility with the old `failed_request_status_codes` option.
|
|
263
|
-
"""
|
|
235
|
+
headers = _filter_headers(headers)
|
|
264
236
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
237
|
+
for header, value in headers.items():
|
|
238
|
+
if isinstance(value, AnnotatedValue):
|
|
239
|
+
value = SENSITIVE_DATA_SUBSTITUTE
|
|
240
|
+
attributes[f"http.request.header.{header.lower()}"] = value
|
|
268
241
|
|
|
269
|
-
|
|
270
|
-
# type: (object) -> bool
|
|
271
|
-
return _in_http_status_code_range(item, self._code_ranges)
|
|
242
|
+
return attributes
|