sentry-sdk 3.0.0a1__py2.py3-none-any.whl → 3.0.0a3__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 +2 -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 +11 -18
- sentry_sdk/_werkzeug.py +5 -7
- sentry_sdk/ai/monitoring.py +44 -31
- sentry_sdk/ai/utils.py +3 -4
- sentry_sdk/api.py +75 -87
- sentry_sdk/attachments.py +10 -12
- sentry_sdk/client.py +137 -155
- sentry_sdk/consts.py +430 -174
- 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 +15 -18
- sentry_sdk/integrations/_wsgi_common.py +22 -33
- sentry_sdk/integrations/aiohttp.py +32 -30
- sentry_sdk/integrations/anthropic.py +42 -37
- sentry_sdk/integrations/argv.py +3 -4
- sentry_sdk/integrations/ariadne.py +16 -18
- sentry_sdk/integrations/arq.py +21 -29
- sentry_sdk/integrations/asgi.py +63 -37
- sentry_sdk/integrations/asyncio.py +14 -16
- 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 +18 -16
- sentry_sdk/integrations/bottle.py +25 -34
- sentry_sdk/integrations/celery/__init__.py +41 -61
- sentry_sdk/integrations/celery/beat.py +23 -27
- sentry_sdk/integrations/celery/utils.py +15 -17
- sentry_sdk/integrations/chalice.py +8 -10
- sentry_sdk/integrations/clickhouse_driver.py +21 -31
- sentry_sdk/integrations/cloud_resource_context.py +9 -16
- sentry_sdk/integrations/cohere.py +27 -33
- sentry_sdk/integrations/dedupe.py +5 -8
- sentry_sdk/integrations/django/__init__.py +57 -72
- sentry_sdk/integrations/django/asgi.py +26 -34
- sentry_sdk/integrations/django/caching.py +23 -19
- sentry_sdk/integrations/django/middleware.py +17 -20
- sentry_sdk/integrations/django/signals_handlers.py +11 -10
- sentry_sdk/integrations/django/templates.py +19 -16
- sentry_sdk/integrations/django/transactions.py +16 -11
- sentry_sdk/integrations/django/views.py +6 -10
- 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 +4 -6
- sentry_sdk/integrations/gql.py +16 -17
- sentry_sdk/integrations/graphene.py +13 -12
- sentry_sdk/integrations/grpc/__init__.py +19 -1
- sentry_sdk/integrations/grpc/aio/server.py +15 -14
- sentry_sdk/integrations/grpc/client.py +19 -9
- sentry_sdk/integrations/grpc/consts.py +2 -0
- sentry_sdk/integrations/grpc/server.py +12 -8
- sentry_sdk/integrations/httpx.py +9 -12
- sentry_sdk/integrations/huey.py +13 -20
- sentry_sdk/integrations/huggingface_hub.py +18 -18
- sentry_sdk/integrations/langchain.py +203 -113
- sentry_sdk/integrations/launchdarkly.py +13 -10
- sentry_sdk/integrations/litestar.py +37 -35
- sentry_sdk/integrations/logging.py +52 -65
- sentry_sdk/integrations/loguru.py +127 -57
- sentry_sdk/integrations/modules.py +3 -4
- sentry_sdk/integrations/openai.py +100 -88
- 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 +201 -0
- sentry_sdk/integrations/openfeature.py +11 -6
- sentry_sdk/integrations/pure_eval.py +6 -10
- sentry_sdk/integrations/pymongo.py +13 -17
- 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 +25 -12
- sentry_sdk/integrations/redis/_sync_common.py +19 -13
- 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 +21 -13
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
- sentry_sdk/integrations/redis/utils.py +23 -24
- sentry_sdk/integrations/rq.py +13 -16
- sentry_sdk/integrations/rust_tracing.py +9 -6
- sentry_sdk/integrations/sanic.py +34 -46
- sentry_sdk/integrations/serverless.py +22 -27
- sentry_sdk/integrations/socket.py +27 -15
- 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 +86 -90
- sentry_sdk/integrations/starlite.py +28 -34
- sentry_sdk/integrations/statsig.py +5 -4
- sentry_sdk/integrations/stdlib.py +28 -24
- sentry_sdk/integrations/strawberry.py +62 -49
- sentry_sdk/integrations/sys_exit.py +7 -11
- sentry_sdk/integrations/threading.py +12 -14
- 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 +41 -10
- sentry_sdk/monitor.py +16 -28
- sentry_sdk/opentelemetry/consts.py +11 -4
- sentry_sdk/opentelemetry/contextvars_context.py +26 -16
- sentry_sdk/opentelemetry/propagator.py +38 -21
- sentry_sdk/opentelemetry/sampler.py +51 -34
- sentry_sdk/opentelemetry/scope.py +36 -37
- sentry_sdk/opentelemetry/span_processor.py +48 -58
- sentry_sdk/opentelemetry/tracing.py +58 -14
- sentry_sdk/opentelemetry/utils.py +186 -194
- 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 -273
- sentry_sdk/scrubber.py +22 -26
- sentry_sdk/serializer.py +40 -54
- sentry_sdk/session.py +44 -61
- sentry_sdk/sessions.py +35 -49
- sentry_sdk/spotlight.py +15 -21
- sentry_sdk/tracing.py +121 -187
- sentry_sdk/tracing_utils.py +104 -122
- sentry_sdk/transport.py +131 -157
- sentry_sdk/utils.py +232 -309
- sentry_sdk/worker.py +16 -28
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/METADATA +3 -3
- sentry_sdk-3.0.0a3.dist-info/RECORD +168 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/WHEEL +1 -1
- sentry_sdk-3.0.0a1.dist-info/RECORD +0 -154
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/top_level.txt +0 -0
sentry_sdk/tracing.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
from datetime import datetime
|
|
2
3
|
import json
|
|
3
4
|
import warnings
|
|
@@ -15,7 +16,6 @@ from opentelemetry.trace.status import Status, StatusCode
|
|
|
15
16
|
from opentelemetry.sdk.trace import ReadableSpan
|
|
16
17
|
from opentelemetry.version import __version__ as otel_version
|
|
17
18
|
|
|
18
|
-
import sentry_sdk
|
|
19
19
|
from sentry_sdk.consts import (
|
|
20
20
|
DEFAULT_SPAN_NAME,
|
|
21
21
|
DEFAULT_SPAN_ORIGIN,
|
|
@@ -38,7 +38,10 @@ from sentry_sdk.opentelemetry.utils import (
|
|
|
38
38
|
get_sentry_meta,
|
|
39
39
|
serialize_trace_state,
|
|
40
40
|
)
|
|
41
|
-
from sentry_sdk.tracing_utils import
|
|
41
|
+
from sentry_sdk.tracing_utils import (
|
|
42
|
+
get_span_status_from_http_code,
|
|
43
|
+
_is_span_origin_excluded,
|
|
44
|
+
)
|
|
42
45
|
from sentry_sdk.utils import (
|
|
43
46
|
_serialize_span_attribute,
|
|
44
47
|
get_current_thread_meta,
|
|
@@ -46,29 +49,26 @@ from sentry_sdk.utils import (
|
|
|
46
49
|
should_be_treated_as_error,
|
|
47
50
|
)
|
|
48
51
|
|
|
49
|
-
from typing import TYPE_CHECKING,
|
|
50
|
-
|
|
52
|
+
from typing import TYPE_CHECKING, overload
|
|
51
53
|
|
|
52
54
|
if TYPE_CHECKING:
|
|
53
|
-
from
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
55
|
+
from typing import (
|
|
56
|
+
Callable,
|
|
57
|
+
Any,
|
|
58
|
+
Dict,
|
|
59
|
+
Iterator,
|
|
60
|
+
Optional,
|
|
61
|
+
ParamSpec,
|
|
62
|
+
Tuple,
|
|
63
|
+
Union,
|
|
64
|
+
TypeVar,
|
|
65
|
+
)
|
|
66
|
+
from sentry_sdk._types import SamplingContext
|
|
67
|
+
from sentry_sdk.tracing_utils import Baggage
|
|
63
68
|
|
|
64
69
|
P = ParamSpec("P")
|
|
65
70
|
R = TypeVar("R")
|
|
66
71
|
|
|
67
|
-
from sentry_sdk._types import (
|
|
68
|
-
SamplingContext,
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
from sentry_sdk.tracing_utils import Baggage
|
|
72
72
|
|
|
73
73
|
_FLAGS_CAPACITY = 10
|
|
74
74
|
_OTEL_VERSION = parse_version(otel_version)
|
|
@@ -77,88 +77,65 @@ tracer = otel_trace.get_tracer(__name__)
|
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
class NoOpSpan:
|
|
80
|
-
def __init__(self, **kwargs):
|
|
81
|
-
# type: (Any) -> None
|
|
80
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
82
81
|
pass
|
|
83
82
|
|
|
84
|
-
def __repr__(self):
|
|
85
|
-
# type: () -> str
|
|
83
|
+
def __repr__(self) -> str:
|
|
86
84
|
return "<%s>" % self.__class__.__name__
|
|
87
85
|
|
|
88
86
|
@property
|
|
89
|
-
def root_span(self):
|
|
90
|
-
# type: () -> Optional[Span]
|
|
87
|
+
def root_span(self) -> Optional[Span]:
|
|
91
88
|
return None
|
|
92
89
|
|
|
93
|
-
def start_child(self, **kwargs):
|
|
94
|
-
# type: (**Any) -> NoOpSpan
|
|
90
|
+
def start_child(self, **kwargs: Any) -> NoOpSpan:
|
|
95
91
|
return NoOpSpan()
|
|
96
92
|
|
|
97
|
-
def to_traceparent(self):
|
|
98
|
-
# type: () -> str
|
|
93
|
+
def to_traceparent(self) -> str:
|
|
99
94
|
return ""
|
|
100
95
|
|
|
101
|
-
def to_baggage(self):
|
|
102
|
-
# type: () -> Optional[Baggage]
|
|
96
|
+
def to_baggage(self) -> Optional[Baggage]:
|
|
103
97
|
return None
|
|
104
98
|
|
|
105
|
-
def get_baggage(self):
|
|
106
|
-
# type: () -> Optional[Baggage]
|
|
99
|
+
def get_baggage(self) -> Optional[Baggage]:
|
|
107
100
|
return None
|
|
108
101
|
|
|
109
|
-
def iter_headers(self):
|
|
110
|
-
# type: () -> Iterator[Tuple[str, str]]
|
|
102
|
+
def iter_headers(self) -> Iterator[Tuple[str, str]]:
|
|
111
103
|
return iter(())
|
|
112
104
|
|
|
113
|
-
def set_tag(self, key, value):
|
|
114
|
-
# type: (str, Any) -> None
|
|
105
|
+
def set_tag(self, key: str, value: Any) -> None:
|
|
115
106
|
pass
|
|
116
107
|
|
|
117
|
-
def set_data(self, key, value):
|
|
118
|
-
# type: (str, Any) -> None
|
|
108
|
+
def set_data(self, key: str, value: Any) -> None:
|
|
119
109
|
pass
|
|
120
110
|
|
|
121
|
-
def set_status(self, value):
|
|
122
|
-
# type: (str) -> None
|
|
111
|
+
def set_status(self, value: str) -> None:
|
|
123
112
|
pass
|
|
124
113
|
|
|
125
|
-
def set_http_status(self, http_status):
|
|
126
|
-
# type: (int) -> None
|
|
114
|
+
def set_http_status(self, http_status: int) -> None:
|
|
127
115
|
pass
|
|
128
116
|
|
|
129
|
-
def is_success(self):
|
|
130
|
-
# type: () -> bool
|
|
117
|
+
def is_success(self) -> bool:
|
|
131
118
|
return True
|
|
132
119
|
|
|
133
|
-
def to_json(self):
|
|
134
|
-
# type: () -> Dict[str, Any]
|
|
120
|
+
def to_json(self) -> Dict[str, Any]:
|
|
135
121
|
return {}
|
|
136
122
|
|
|
137
|
-
def get_trace_context(self):
|
|
138
|
-
# type: () -> Any
|
|
123
|
+
def get_trace_context(self) -> Any:
|
|
139
124
|
return {}
|
|
140
125
|
|
|
141
|
-
def get_profile_context(self):
|
|
142
|
-
# type: () -> Any
|
|
126
|
+
def get_profile_context(self) -> Any:
|
|
143
127
|
return {}
|
|
144
128
|
|
|
145
|
-
def finish(
|
|
146
|
-
self,
|
|
147
|
-
end_timestamp=None, # type: Optional[Union[float, datetime]]
|
|
148
|
-
):
|
|
149
|
-
# type: (...) -> None
|
|
129
|
+
def finish(self, end_timestamp: Optional[Union[float, datetime]] = None) -> None:
|
|
150
130
|
pass
|
|
151
131
|
|
|
152
|
-
def set_context(self, key, value):
|
|
153
|
-
# type: (str, dict[str, Any]) -> None
|
|
132
|
+
def set_context(self, key: str, value: dict[str, Any]) -> None:
|
|
154
133
|
pass
|
|
155
134
|
|
|
156
|
-
def init_span_recorder(self, maxlen):
|
|
157
|
-
# type: (int) -> None
|
|
135
|
+
def init_span_recorder(self, maxlen: int) -> None:
|
|
158
136
|
pass
|
|
159
137
|
|
|
160
|
-
def _set_initial_sampling_decision(self, sampling_context):
|
|
161
|
-
# type: (SamplingContext) -> None
|
|
138
|
+
def _set_initial_sampling_decision(self, sampling_context: SamplingContext) -> None:
|
|
162
139
|
pass
|
|
163
140
|
|
|
164
141
|
|
|
@@ -170,26 +147,25 @@ class Span:
|
|
|
170
147
|
def __init__(
|
|
171
148
|
self,
|
|
172
149
|
*,
|
|
173
|
-
op
|
|
174
|
-
description
|
|
175
|
-
status
|
|
176
|
-
sampled
|
|
177
|
-
start_timestamp
|
|
178
|
-
origin
|
|
179
|
-
name
|
|
180
|
-
source=TransactionSource.CUSTOM,
|
|
181
|
-
attributes
|
|
182
|
-
only_if_parent=False,
|
|
183
|
-
parent_span
|
|
184
|
-
otel_span
|
|
185
|
-
span
|
|
186
|
-
):
|
|
187
|
-
# type: (...) -> None
|
|
150
|
+
op: Optional[str] = None,
|
|
151
|
+
description: Optional[str] = None,
|
|
152
|
+
status: Optional[str] = None,
|
|
153
|
+
sampled: Optional[bool] = None,
|
|
154
|
+
start_timestamp: Optional[Union[datetime, float]] = None,
|
|
155
|
+
origin: Optional[str] = None,
|
|
156
|
+
name: Optional[str] = None,
|
|
157
|
+
source: str = TransactionSource.CUSTOM,
|
|
158
|
+
attributes: Optional[dict[str, Any]] = None,
|
|
159
|
+
only_if_parent: bool = False,
|
|
160
|
+
parent_span: Optional[Span] = None,
|
|
161
|
+
otel_span: Optional[OtelSpan] = None,
|
|
162
|
+
span: Optional[Span] = None,
|
|
163
|
+
) -> None:
|
|
188
164
|
"""
|
|
189
165
|
If otel_span is passed explicitly, just acts as a proxy.
|
|
190
166
|
|
|
191
167
|
If span is passed explicitly, use it. The only purpose of this param
|
|
192
|
-
|
|
168
|
+
is backwards compatibility with start_transaction(transaction=...).
|
|
193
169
|
|
|
194
170
|
If only_if_parent is True, just return an INVALID_SPAN
|
|
195
171
|
and avoid instrumentation if there's no active parent span.
|
|
@@ -206,15 +182,18 @@ class Span:
|
|
|
206
182
|
not parent_span_context.is_valid or parent_span_context.is_remote
|
|
207
183
|
)
|
|
208
184
|
|
|
185
|
+
origin = origin or DEFAULT_SPAN_ORIGIN
|
|
186
|
+
if not skip_span and _is_span_origin_excluded(origin):
|
|
187
|
+
skip_span = True
|
|
188
|
+
|
|
209
189
|
if skip_span:
|
|
210
190
|
self._otel_span = INVALID_SPAN
|
|
211
191
|
else:
|
|
212
|
-
|
|
213
192
|
if start_timestamp is not None:
|
|
214
193
|
# OTel timestamps have nanosecond precision
|
|
215
194
|
start_timestamp = convert_to_otel_timestamp(start_timestamp)
|
|
216
195
|
|
|
217
|
-
span_name = name or description or
|
|
196
|
+
span_name = name or description or DEFAULT_SPAN_NAME
|
|
218
197
|
|
|
219
198
|
# Prepopulate some attrs so that they're accessible in traces_sampler
|
|
220
199
|
attributes = attributes or {}
|
|
@@ -240,7 +219,7 @@ class Span:
|
|
|
240
219
|
attributes=attributes,
|
|
241
220
|
)
|
|
242
221
|
|
|
243
|
-
self.origin = origin
|
|
222
|
+
self.origin = origin
|
|
244
223
|
self.description = description
|
|
245
224
|
self.name = span_name
|
|
246
225
|
|
|
@@ -249,14 +228,12 @@ class Span:
|
|
|
249
228
|
|
|
250
229
|
self.update_active_thread()
|
|
251
230
|
|
|
252
|
-
def __eq__(self, other):
|
|
253
|
-
# type: (object) -> bool
|
|
231
|
+
def __eq__(self, other: object) -> bool:
|
|
254
232
|
if not isinstance(other, Span):
|
|
255
233
|
return False
|
|
256
234
|
return self._otel_span == other._otel_span
|
|
257
235
|
|
|
258
|
-
def __repr__(self):
|
|
259
|
-
# type: () -> str
|
|
236
|
+
def __repr__(self) -> str:
|
|
260
237
|
return (
|
|
261
238
|
"<%s(op=%r, name:%r, trace_id=%r, span_id=%r, parent_span_id=%r, sampled=%r, origin=%r)>"
|
|
262
239
|
% (
|
|
@@ -271,23 +248,23 @@ class Span:
|
|
|
271
248
|
)
|
|
272
249
|
)
|
|
273
250
|
|
|
274
|
-
def
|
|
275
|
-
# type: () -> Span
|
|
276
|
-
# XXX use_span? https://github.com/open-telemetry/opentelemetry-python/blob/3836da8543ce9751051e38a110c0468724042e62/opentelemetry-api/src/opentelemetry/trace/__init__.py#L547
|
|
277
|
-
#
|
|
278
|
-
# create a Context object with parent set as current span
|
|
251
|
+
def activate(self) -> None:
|
|
279
252
|
ctx = otel_trace.set_span_in_context(self._otel_span)
|
|
280
253
|
# set as the implicit current context
|
|
281
254
|
self._ctx_token = context.attach(ctx)
|
|
282
255
|
|
|
283
|
-
|
|
284
|
-
self
|
|
285
|
-
|
|
256
|
+
def deactivate(self) -> None:
|
|
257
|
+
if hasattr(self, "_ctx_token"):
|
|
258
|
+
context.detach(self._ctx_token)
|
|
259
|
+
del self._ctx_token
|
|
286
260
|
|
|
261
|
+
def __enter__(self) -> Span:
|
|
262
|
+
self.activate()
|
|
287
263
|
return self
|
|
288
264
|
|
|
289
|
-
def __exit__(
|
|
290
|
-
|
|
265
|
+
def __exit__(
|
|
266
|
+
self, ty: Optional[Any], value: Optional[Any], tb: Optional[Any]
|
|
267
|
+
) -> None:
|
|
291
268
|
if value is not None and should_be_treated_as_error(ty, value):
|
|
292
269
|
self.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
293
270
|
else:
|
|
@@ -299,45 +276,37 @@ class Span:
|
|
|
299
276
|
self.set_status(SPANSTATUS.OK)
|
|
300
277
|
|
|
301
278
|
self.finish()
|
|
302
|
-
|
|
303
|
-
del self._ctx_token
|
|
279
|
+
self.deactivate()
|
|
304
280
|
|
|
305
281
|
@property
|
|
306
|
-
def description(self):
|
|
307
|
-
# type: () -> Optional[str]
|
|
282
|
+
def description(self) -> Optional[str]:
|
|
308
283
|
return self.get_attribute(SentrySpanAttribute.DESCRIPTION)
|
|
309
284
|
|
|
310
285
|
@description.setter
|
|
311
|
-
def description(self, value):
|
|
312
|
-
# type: (Optional[str]) -> None
|
|
286
|
+
def description(self, value: Optional[str]) -> None:
|
|
313
287
|
self.set_attribute(SentrySpanAttribute.DESCRIPTION, value)
|
|
314
288
|
|
|
315
289
|
@property
|
|
316
|
-
def origin(self):
|
|
317
|
-
# type: () -> Optional[str]
|
|
290
|
+
def origin(self) -> Optional[str]:
|
|
318
291
|
return self.get_attribute(SentrySpanAttribute.ORIGIN)
|
|
319
292
|
|
|
320
293
|
@origin.setter
|
|
321
|
-
def origin(self, value):
|
|
322
|
-
# type: (Optional[str]) -> None
|
|
294
|
+
def origin(self, value: Optional[str]) -> None:
|
|
323
295
|
self.set_attribute(SentrySpanAttribute.ORIGIN, value)
|
|
324
296
|
|
|
325
297
|
@property
|
|
326
|
-
def root_span(self):
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
"Optional[OtelSpan]", get_sentry_meta(self._otel_span, "root_span")
|
|
298
|
+
def root_span(self) -> Optional[Span]:
|
|
299
|
+
root_otel_span: Optional[OtelSpan] = get_sentry_meta(
|
|
300
|
+
self._otel_span, "root_span"
|
|
330
301
|
)
|
|
331
302
|
return Span(otel_span=root_otel_span) if root_otel_span else None
|
|
332
303
|
|
|
333
304
|
@property
|
|
334
|
-
def is_root_span(self):
|
|
335
|
-
# type: () -> bool
|
|
305
|
+
def is_root_span(self) -> bool:
|
|
336
306
|
return self.root_span == self
|
|
337
307
|
|
|
338
308
|
@property
|
|
339
|
-
def parent_span_id(self):
|
|
340
|
-
# type: () -> Optional[str]
|
|
309
|
+
def parent_span_id(self) -> Optional[str]:
|
|
341
310
|
if (
|
|
342
311
|
not isinstance(self._otel_span, ReadableSpan)
|
|
343
312
|
or self._otel_span.parent is None
|
|
@@ -346,70 +315,58 @@ class Span:
|
|
|
346
315
|
return format_span_id(self._otel_span.parent.span_id)
|
|
347
316
|
|
|
348
317
|
@property
|
|
349
|
-
def trace_id(self):
|
|
350
|
-
# type: () -> str
|
|
318
|
+
def trace_id(self) -> str:
|
|
351
319
|
return format_trace_id(self._otel_span.get_span_context().trace_id)
|
|
352
320
|
|
|
353
321
|
@property
|
|
354
|
-
def span_id(self):
|
|
355
|
-
# type: () -> str
|
|
322
|
+
def span_id(self) -> str:
|
|
356
323
|
return format_span_id(self._otel_span.get_span_context().span_id)
|
|
357
324
|
|
|
358
325
|
@property
|
|
359
|
-
def is_valid(self):
|
|
360
|
-
# type: () -> bool
|
|
326
|
+
def is_valid(self) -> bool:
|
|
361
327
|
return self._otel_span.get_span_context().is_valid and isinstance(
|
|
362
328
|
self._otel_span, ReadableSpan
|
|
363
329
|
)
|
|
364
330
|
|
|
365
331
|
@property
|
|
366
|
-
def sampled(self):
|
|
367
|
-
# type: () -> Optional[bool]
|
|
332
|
+
def sampled(self) -> Optional[bool]:
|
|
368
333
|
return self._otel_span.get_span_context().trace_flags.sampled
|
|
369
334
|
|
|
370
335
|
@property
|
|
371
|
-
def sample_rate(self):
|
|
372
|
-
# type: () -> Optional[float]
|
|
336
|
+
def sample_rate(self) -> Optional[float]:
|
|
373
337
|
sample_rate = self._otel_span.get_span_context().trace_state.get(
|
|
374
338
|
TRACESTATE_SAMPLE_RATE_KEY
|
|
375
339
|
)
|
|
376
340
|
return float(sample_rate) if sample_rate is not None else None
|
|
377
341
|
|
|
378
342
|
@property
|
|
379
|
-
def op(self):
|
|
380
|
-
# type: () -> Optional[str]
|
|
343
|
+
def op(self) -> Optional[str]:
|
|
381
344
|
return self.get_attribute(SentrySpanAttribute.OP)
|
|
382
345
|
|
|
383
346
|
@op.setter
|
|
384
|
-
def op(self, value):
|
|
385
|
-
# type: (Optional[str]) -> None
|
|
347
|
+
def op(self, value: Optional[str]) -> None:
|
|
386
348
|
self.set_attribute(SentrySpanAttribute.OP, value)
|
|
387
349
|
|
|
388
350
|
@property
|
|
389
|
-
def name(self):
|
|
390
|
-
# type: () -> Optional[str]
|
|
351
|
+
def name(self) -> Optional[str]:
|
|
391
352
|
return self.get_attribute(SentrySpanAttribute.NAME)
|
|
392
353
|
|
|
393
354
|
@name.setter
|
|
394
|
-
def name(self, value):
|
|
395
|
-
# type: (Optional[str]) -> None
|
|
355
|
+
def name(self, value: Optional[str]) -> None:
|
|
396
356
|
self.set_attribute(SentrySpanAttribute.NAME, value)
|
|
397
357
|
|
|
398
358
|
@property
|
|
399
|
-
def source(self):
|
|
400
|
-
# type: () -> str
|
|
359
|
+
def source(self) -> str:
|
|
401
360
|
return (
|
|
402
361
|
self.get_attribute(SentrySpanAttribute.SOURCE) or TransactionSource.CUSTOM
|
|
403
362
|
)
|
|
404
363
|
|
|
405
364
|
@source.setter
|
|
406
|
-
def source(self, value):
|
|
407
|
-
# type: (str) -> None
|
|
365
|
+
def source(self, value: str) -> None:
|
|
408
366
|
self.set_attribute(SentrySpanAttribute.SOURCE, value)
|
|
409
367
|
|
|
410
368
|
@property
|
|
411
|
-
def start_timestamp(self):
|
|
412
|
-
# type: () -> Optional[datetime]
|
|
369
|
+
def start_timestamp(self) -> Optional[datetime]:
|
|
413
370
|
if not isinstance(self._otel_span, ReadableSpan):
|
|
414
371
|
return None
|
|
415
372
|
|
|
@@ -420,8 +377,7 @@ class Span:
|
|
|
420
377
|
return convert_from_otel_timestamp(start_time)
|
|
421
378
|
|
|
422
379
|
@property
|
|
423
|
-
def timestamp(self):
|
|
424
|
-
# type: () -> Optional[datetime]
|
|
380
|
+
def timestamp(self) -> Optional[datetime]:
|
|
425
381
|
if not isinstance(self._otel_span, ReadableSpan):
|
|
426
382
|
return None
|
|
427
383
|
|
|
@@ -431,17 +387,14 @@ class Span:
|
|
|
431
387
|
|
|
432
388
|
return convert_from_otel_timestamp(end_time)
|
|
433
389
|
|
|
434
|
-
def start_child(self, **kwargs):
|
|
435
|
-
# type: (**Any) -> Span
|
|
390
|
+
def start_child(self, **kwargs: Any) -> Span:
|
|
436
391
|
return Span(parent_span=self, **kwargs)
|
|
437
392
|
|
|
438
|
-
def iter_headers(self):
|
|
439
|
-
# type: () -> Iterator[Tuple[str, str]]
|
|
393
|
+
def iter_headers(self) -> Iterator[Tuple[str, str]]:
|
|
440
394
|
yield SENTRY_TRACE_HEADER_NAME, self.to_traceparent()
|
|
441
395
|
yield BAGGAGE_HEADER_NAME, serialize_trace_state(self.trace_state)
|
|
442
396
|
|
|
443
|
-
def to_traceparent(self):
|
|
444
|
-
# type: () -> str
|
|
397
|
+
def to_traceparent(self) -> str:
|
|
445
398
|
if self.sampled is True:
|
|
446
399
|
sampled = "1"
|
|
447
400
|
elif self.sampled is False:
|
|
@@ -456,24 +409,19 @@ class Span:
|
|
|
456
409
|
return traceparent
|
|
457
410
|
|
|
458
411
|
@property
|
|
459
|
-
def trace_state(self):
|
|
460
|
-
# type: () -> TraceState
|
|
412
|
+
def trace_state(self) -> TraceState:
|
|
461
413
|
return get_trace_state(self._otel_span)
|
|
462
414
|
|
|
463
|
-
def to_baggage(self):
|
|
464
|
-
# type: () -> Baggage
|
|
415
|
+
def to_baggage(self) -> Baggage:
|
|
465
416
|
return self.get_baggage()
|
|
466
417
|
|
|
467
|
-
def get_baggage(self):
|
|
468
|
-
# type: () -> Baggage
|
|
418
|
+
def get_baggage(self) -> Baggage:
|
|
469
419
|
return baggage_from_trace_state(self.trace_state)
|
|
470
420
|
|
|
471
|
-
def set_tag(self, key, value):
|
|
472
|
-
# type: (str, Any) -> None
|
|
421
|
+
def set_tag(self, key: str, value: Any) -> None:
|
|
473
422
|
self.set_attribute(f"{SentrySpanAttribute.TAG}.{key}", value)
|
|
474
423
|
|
|
475
|
-
def set_data(self, key, value):
|
|
476
|
-
# type: (str, Any) -> None
|
|
424
|
+
def set_data(self, key: str, value: Any) -> None:
|
|
477
425
|
warnings.warn(
|
|
478
426
|
"`Span.set_data` is deprecated. Please use `Span.set_attribute` instead.",
|
|
479
427
|
DeprecationWarning,
|
|
@@ -483,8 +431,7 @@ class Span:
|
|
|
483
431
|
# TODO-neel-potel we cannot add dicts here
|
|
484
432
|
self.set_attribute(key, value)
|
|
485
433
|
|
|
486
|
-
def get_attribute(self, name):
|
|
487
|
-
# type: (str) -> Optional[Any]
|
|
434
|
+
def get_attribute(self, name: str) -> Optional[Any]:
|
|
488
435
|
if (
|
|
489
436
|
not isinstance(self._otel_span, ReadableSpan)
|
|
490
437
|
or not self._otel_span.attributes
|
|
@@ -492,8 +439,7 @@ class Span:
|
|
|
492
439
|
return None
|
|
493
440
|
return self._otel_span.attributes.get(name)
|
|
494
441
|
|
|
495
|
-
def set_attribute(self, key, value):
|
|
496
|
-
# type: (str, Any) -> None
|
|
442
|
+
def set_attribute(self, key: str, value: Any) -> None:
|
|
497
443
|
# otel doesn't support None as values, preferring to not set the key
|
|
498
444
|
# at all instead
|
|
499
445
|
if value is None:
|
|
@@ -505,8 +451,7 @@ class Span:
|
|
|
505
451
|
self._otel_span.set_attribute(key, serialized_value)
|
|
506
452
|
|
|
507
453
|
@property
|
|
508
|
-
def status(self):
|
|
509
|
-
# type: () -> Optional[str]
|
|
454
|
+
def status(self) -> Optional[str]:
|
|
510
455
|
"""
|
|
511
456
|
Return the Sentry `SPANSTATUS` corresponding to the underlying OTel status.
|
|
512
457
|
Because differences in possible values in OTel `StatusCode` and
|
|
@@ -523,8 +468,7 @@ class Span:
|
|
|
523
468
|
else:
|
|
524
469
|
return SPANSTATUS.UNKNOWN_ERROR
|
|
525
470
|
|
|
526
|
-
def set_status(self, status):
|
|
527
|
-
# type: (str) -> None
|
|
471
|
+
def set_status(self, status: str) -> None:
|
|
528
472
|
if status == SPANSTATUS.OK:
|
|
529
473
|
otel_status = StatusCode.OK
|
|
530
474
|
otel_description = None
|
|
@@ -537,37 +481,31 @@ class Span:
|
|
|
537
481
|
else:
|
|
538
482
|
self._otel_span.set_status(Status(otel_status, otel_description))
|
|
539
483
|
|
|
540
|
-
def set_thread(self, thread_id, thread_name):
|
|
541
|
-
# type: (Optional[int], Optional[str]) -> None
|
|
484
|
+
def set_thread(self, thread_id: Optional[int], thread_name: Optional[str]) -> None:
|
|
542
485
|
if thread_id is not None:
|
|
543
486
|
self.set_attribute(SPANDATA.THREAD_ID, str(thread_id))
|
|
544
487
|
|
|
545
488
|
if thread_name is not None:
|
|
546
489
|
self.set_attribute(SPANDATA.THREAD_NAME, thread_name)
|
|
547
490
|
|
|
548
|
-
def update_active_thread(self):
|
|
549
|
-
# type: () -> None
|
|
491
|
+
def update_active_thread(self) -> None:
|
|
550
492
|
thread_id, thread_name = get_current_thread_meta()
|
|
551
493
|
self.set_thread(thread_id, thread_name)
|
|
552
494
|
|
|
553
|
-
def set_http_status(self, http_status):
|
|
554
|
-
# type: (int) -> None
|
|
495
|
+
def set_http_status(self, http_status: int) -> None:
|
|
555
496
|
self.set_attribute(SPANDATA.HTTP_STATUS_CODE, http_status)
|
|
556
497
|
self.set_status(get_span_status_from_http_code(http_status))
|
|
557
498
|
|
|
558
|
-
def is_success(self):
|
|
559
|
-
# type: () -> bool
|
|
499
|
+
def is_success(self) -> bool:
|
|
560
500
|
return self.status == SPANSTATUS.OK
|
|
561
501
|
|
|
562
|
-
def finish(self, end_timestamp=None):
|
|
563
|
-
# type: (Optional[Union[float, datetime]]) -> None
|
|
502
|
+
def finish(self, end_timestamp: Optional[Union[float, datetime]] = None) -> None:
|
|
564
503
|
if end_timestamp is not None:
|
|
565
504
|
self._otel_span.end(convert_to_otel_timestamp(end_timestamp))
|
|
566
505
|
else:
|
|
567
506
|
self._otel_span.end()
|
|
568
507
|
|
|
569
|
-
def to_json(self):
|
|
570
|
-
# type: () -> dict[str, Any]
|
|
508
|
+
def to_json(self) -> dict[str, Any]:
|
|
571
509
|
"""
|
|
572
510
|
Only meant for testing. Not used internally anymore.
|
|
573
511
|
"""
|
|
@@ -575,21 +513,18 @@ class Span:
|
|
|
575
513
|
return {}
|
|
576
514
|
return json.loads(self._otel_span.to_json())
|
|
577
515
|
|
|
578
|
-
def get_trace_context(self):
|
|
579
|
-
# type: () -> dict[str, Any]
|
|
516
|
+
def get_trace_context(self) -> dict[str, Any]:
|
|
580
517
|
if not isinstance(self._otel_span, ReadableSpan):
|
|
581
518
|
return {}
|
|
582
519
|
|
|
583
520
|
return get_trace_context(self._otel_span)
|
|
584
521
|
|
|
585
|
-
def set_context(self, key, value):
|
|
586
|
-
# type: (str, Any) -> None
|
|
522
|
+
def set_context(self, key: str, value: Any) -> None:
|
|
587
523
|
# TODO-neel-potel we cannot add dicts here
|
|
588
524
|
|
|
589
525
|
self.set_attribute(f"{SentrySpanAttribute.CONTEXT}.{key}", value)
|
|
590
526
|
|
|
591
|
-
def set_flag(self, flag, value):
|
|
592
|
-
# type: (str, bool) -> None
|
|
527
|
+
def set_flag(self, flag: str, value: bool) -> None:
|
|
593
528
|
flag_count = self.get_attribute("_flag.count") or 0
|
|
594
529
|
if flag_count < _FLAGS_CAPACITY:
|
|
595
530
|
self.set_attribute(f"flag.evaluation.{flag}", value)
|
|
@@ -603,18 +538,17 @@ Transaction = Span
|
|
|
603
538
|
if TYPE_CHECKING:
|
|
604
539
|
|
|
605
540
|
@overload
|
|
606
|
-
def trace(func=None):
|
|
607
|
-
# type: (None) -> Callable[[Callable[P, R]], Callable[P, R]]
|
|
541
|
+
def trace(func: None = None) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
608
542
|
pass
|
|
609
543
|
|
|
610
544
|
@overload
|
|
611
|
-
def trace(func):
|
|
612
|
-
# type: (Callable[P, R]) -> Callable[P, R]
|
|
545
|
+
def trace(func: Callable[P, R]) -> Callable[P, R]:
|
|
613
546
|
pass
|
|
614
547
|
|
|
615
548
|
|
|
616
|
-
def trace(
|
|
617
|
-
|
|
549
|
+
def trace(
|
|
550
|
+
func: Optional[Callable[P, R]] = None,
|
|
551
|
+
) -> Union[Callable[P, R], Callable[[Callable[P, R]], Callable[P, R]]]:
|
|
618
552
|
"""
|
|
619
553
|
Decorator to start a child span under the existing current transaction.
|
|
620
554
|
If there is no current transaction, then nothing will be traced.
|