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.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
|
|
@@ -37,7 +38,10 @@ from sentry_sdk.opentelemetry.utils import (
|
|
|
37
38
|
get_sentry_meta,
|
|
38
39
|
serialize_trace_state,
|
|
39
40
|
)
|
|
40
|
-
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
|
+
)
|
|
41
45
|
from sentry_sdk.utils import (
|
|
42
46
|
_serialize_span_attribute,
|
|
43
47
|
get_current_thread_meta,
|
|
@@ -45,29 +49,26 @@ from sentry_sdk.utils import (
|
|
|
45
49
|
should_be_treated_as_error,
|
|
46
50
|
)
|
|
47
51
|
|
|
48
|
-
from typing import TYPE_CHECKING,
|
|
49
|
-
|
|
52
|
+
from typing import TYPE_CHECKING, overload
|
|
50
53
|
|
|
51
54
|
if TYPE_CHECKING:
|
|
52
|
-
from
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
|
62
68
|
|
|
63
69
|
P = ParamSpec("P")
|
|
64
70
|
R = TypeVar("R")
|
|
65
71
|
|
|
66
|
-
from sentry_sdk._types import (
|
|
67
|
-
SamplingContext,
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
from sentry_sdk.tracing_utils import Baggage
|
|
71
72
|
|
|
72
73
|
_FLAGS_CAPACITY = 10
|
|
73
74
|
_OTEL_VERSION = parse_version(otel_version)
|
|
@@ -76,88 +77,65 @@ tracer = otel_trace.get_tracer(__name__)
|
|
|
76
77
|
|
|
77
78
|
|
|
78
79
|
class NoOpSpan:
|
|
79
|
-
def __init__(self, **kwargs):
|
|
80
|
-
# type: (Any) -> None
|
|
80
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
81
81
|
pass
|
|
82
82
|
|
|
83
|
-
def __repr__(self):
|
|
84
|
-
# type: () -> str
|
|
83
|
+
def __repr__(self) -> str:
|
|
85
84
|
return "<%s>" % self.__class__.__name__
|
|
86
85
|
|
|
87
86
|
@property
|
|
88
|
-
def root_span(self):
|
|
89
|
-
# type: () -> Optional[Span]
|
|
87
|
+
def root_span(self) -> Optional[Span]:
|
|
90
88
|
return None
|
|
91
89
|
|
|
92
|
-
def start_child(self, **kwargs):
|
|
93
|
-
# type: (**Any) -> NoOpSpan
|
|
90
|
+
def start_child(self, **kwargs: Any) -> NoOpSpan:
|
|
94
91
|
return NoOpSpan()
|
|
95
92
|
|
|
96
|
-
def to_traceparent(self):
|
|
97
|
-
# type: () -> str
|
|
93
|
+
def to_traceparent(self) -> str:
|
|
98
94
|
return ""
|
|
99
95
|
|
|
100
|
-
def to_baggage(self):
|
|
101
|
-
# type: () -> Optional[Baggage]
|
|
96
|
+
def to_baggage(self) -> Optional[Baggage]:
|
|
102
97
|
return None
|
|
103
98
|
|
|
104
|
-
def get_baggage(self):
|
|
105
|
-
# type: () -> Optional[Baggage]
|
|
99
|
+
def get_baggage(self) -> Optional[Baggage]:
|
|
106
100
|
return None
|
|
107
101
|
|
|
108
|
-
def iter_headers(self):
|
|
109
|
-
# type: () -> Iterator[Tuple[str, str]]
|
|
102
|
+
def iter_headers(self) -> Iterator[Tuple[str, str]]:
|
|
110
103
|
return iter(())
|
|
111
104
|
|
|
112
|
-
def set_tag(self, key, value):
|
|
113
|
-
# type: (str, Any) -> None
|
|
105
|
+
def set_tag(self, key: str, value: Any) -> None:
|
|
114
106
|
pass
|
|
115
107
|
|
|
116
|
-
def set_data(self, key, value):
|
|
117
|
-
# type: (str, Any) -> None
|
|
108
|
+
def set_data(self, key: str, value: Any) -> None:
|
|
118
109
|
pass
|
|
119
110
|
|
|
120
|
-
def set_status(self, value):
|
|
121
|
-
# type: (str) -> None
|
|
111
|
+
def set_status(self, value: str) -> None:
|
|
122
112
|
pass
|
|
123
113
|
|
|
124
|
-
def set_http_status(self, http_status):
|
|
125
|
-
# type: (int) -> None
|
|
114
|
+
def set_http_status(self, http_status: int) -> None:
|
|
126
115
|
pass
|
|
127
116
|
|
|
128
|
-
def is_success(self):
|
|
129
|
-
# type: () -> bool
|
|
117
|
+
def is_success(self) -> bool:
|
|
130
118
|
return True
|
|
131
119
|
|
|
132
|
-
def to_json(self):
|
|
133
|
-
# type: () -> Dict[str, Any]
|
|
120
|
+
def to_json(self) -> Dict[str, Any]:
|
|
134
121
|
return {}
|
|
135
122
|
|
|
136
|
-
def get_trace_context(self):
|
|
137
|
-
# type: () -> Any
|
|
123
|
+
def get_trace_context(self) -> Any:
|
|
138
124
|
return {}
|
|
139
125
|
|
|
140
|
-
def get_profile_context(self):
|
|
141
|
-
# type: () -> Any
|
|
126
|
+
def get_profile_context(self) -> Any:
|
|
142
127
|
return {}
|
|
143
128
|
|
|
144
|
-
def finish(
|
|
145
|
-
self,
|
|
146
|
-
end_timestamp=None, # type: Optional[Union[float, datetime]]
|
|
147
|
-
):
|
|
148
|
-
# type: (...) -> None
|
|
129
|
+
def finish(self, end_timestamp: Optional[Union[float, datetime]] = None) -> None:
|
|
149
130
|
pass
|
|
150
131
|
|
|
151
|
-
def set_context(self, key, value):
|
|
152
|
-
# type: (str, dict[str, Any]) -> None
|
|
132
|
+
def set_context(self, key: str, value: dict[str, Any]) -> None:
|
|
153
133
|
pass
|
|
154
134
|
|
|
155
|
-
def init_span_recorder(self, maxlen):
|
|
156
|
-
# type: (int) -> None
|
|
135
|
+
def init_span_recorder(self, maxlen: int) -> None:
|
|
157
136
|
pass
|
|
158
137
|
|
|
159
|
-
def _set_initial_sampling_decision(self, sampling_context):
|
|
160
|
-
# type: (SamplingContext) -> None
|
|
138
|
+
def _set_initial_sampling_decision(self, sampling_context: SamplingContext) -> None:
|
|
161
139
|
pass
|
|
162
140
|
|
|
163
141
|
|
|
@@ -169,28 +147,27 @@ class Span:
|
|
|
169
147
|
def __init__(
|
|
170
148
|
self,
|
|
171
149
|
*,
|
|
172
|
-
op
|
|
173
|
-
description
|
|
174
|
-
status
|
|
175
|
-
sampled
|
|
176
|
-
start_timestamp
|
|
177
|
-
origin
|
|
178
|
-
name
|
|
179
|
-
source=TransactionSource.CUSTOM,
|
|
180
|
-
attributes
|
|
181
|
-
|
|
182
|
-
parent_span
|
|
183
|
-
otel_span
|
|
184
|
-
span
|
|
185
|
-
):
|
|
186
|
-
# 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_as_child_span: bool = False,
|
|
160
|
+
parent_span: Optional[Span] = None,
|
|
161
|
+
otel_span: Optional[OtelSpan] = None,
|
|
162
|
+
span: Optional[Span] = None,
|
|
163
|
+
) -> None:
|
|
187
164
|
"""
|
|
188
165
|
If otel_span is passed explicitly, just acts as a proxy.
|
|
189
166
|
|
|
190
167
|
If span is passed explicitly, use it. The only purpose of this param
|
|
191
168
|
is backwards compatibility with start_transaction(transaction=...).
|
|
192
169
|
|
|
193
|
-
If
|
|
170
|
+
If only_as_child_span is True, just return an INVALID_SPAN
|
|
194
171
|
and avoid instrumentation if there's no active parent span.
|
|
195
172
|
"""
|
|
196
173
|
if otel_span is not None:
|
|
@@ -199,21 +176,24 @@ class Span:
|
|
|
199
176
|
self._otel_span = span._otel_span
|
|
200
177
|
else:
|
|
201
178
|
skip_span = False
|
|
202
|
-
if
|
|
179
|
+
if only_as_child_span and parent_span is None:
|
|
203
180
|
parent_span_context = get_current_span().get_span_context()
|
|
204
181
|
skip_span = (
|
|
205
182
|
not parent_span_context.is_valid or parent_span_context.is_remote
|
|
206
183
|
)
|
|
207
184
|
|
|
185
|
+
origin = origin or DEFAULT_SPAN_ORIGIN
|
|
186
|
+
if not skip_span and _is_span_origin_excluded(origin):
|
|
187
|
+
skip_span = True
|
|
188
|
+
|
|
208
189
|
if skip_span:
|
|
209
190
|
self._otel_span = INVALID_SPAN
|
|
210
191
|
else:
|
|
211
|
-
|
|
212
192
|
if start_timestamp is not None:
|
|
213
193
|
# OTel timestamps have nanosecond precision
|
|
214
194
|
start_timestamp = convert_to_otel_timestamp(start_timestamp)
|
|
215
195
|
|
|
216
|
-
span_name = name or description or
|
|
196
|
+
span_name = name or description or DEFAULT_SPAN_NAME
|
|
217
197
|
|
|
218
198
|
# Prepopulate some attrs so that they're accessible in traces_sampler
|
|
219
199
|
attributes = attributes or {}
|
|
@@ -239,7 +219,7 @@ class Span:
|
|
|
239
219
|
attributes=attributes,
|
|
240
220
|
)
|
|
241
221
|
|
|
242
|
-
self.origin = origin
|
|
222
|
+
self.origin = origin
|
|
243
223
|
self.description = description
|
|
244
224
|
self.name = span_name
|
|
245
225
|
|
|
@@ -248,14 +228,12 @@ class Span:
|
|
|
248
228
|
|
|
249
229
|
self.update_active_thread()
|
|
250
230
|
|
|
251
|
-
def __eq__(self, other):
|
|
252
|
-
# type: (object) -> bool
|
|
231
|
+
def __eq__(self, other: object) -> bool:
|
|
253
232
|
if not isinstance(other, Span):
|
|
254
233
|
return False
|
|
255
234
|
return self._otel_span == other._otel_span
|
|
256
235
|
|
|
257
|
-
def __repr__(self):
|
|
258
|
-
# type: () -> str
|
|
236
|
+
def __repr__(self) -> str:
|
|
259
237
|
return (
|
|
260
238
|
"<%s(op=%r, name:%r, trace_id=%r, span_id=%r, parent_span_id=%r, sampled=%r, origin=%r)>"
|
|
261
239
|
% (
|
|
@@ -270,25 +248,23 @@ class Span:
|
|
|
270
248
|
)
|
|
271
249
|
)
|
|
272
250
|
|
|
273
|
-
def activate(self):
|
|
274
|
-
# type: () -> None
|
|
251
|
+
def activate(self) -> None:
|
|
275
252
|
ctx = otel_trace.set_span_in_context(self._otel_span)
|
|
276
253
|
# set as the implicit current context
|
|
277
254
|
self._ctx_token = context.attach(ctx)
|
|
278
255
|
|
|
279
|
-
def deactivate(self):
|
|
280
|
-
|
|
281
|
-
if self._ctx_token:
|
|
256
|
+
def deactivate(self) -> None:
|
|
257
|
+
if hasattr(self, "_ctx_token"):
|
|
282
258
|
context.detach(self._ctx_token)
|
|
283
259
|
del self._ctx_token
|
|
284
260
|
|
|
285
|
-
def __enter__(self):
|
|
286
|
-
# type: () -> Span
|
|
261
|
+
def __enter__(self) -> Span:
|
|
287
262
|
self.activate()
|
|
288
263
|
return self
|
|
289
264
|
|
|
290
|
-
def __exit__(
|
|
291
|
-
|
|
265
|
+
def __exit__(
|
|
266
|
+
self, ty: Optional[Any], value: Optional[Any], tb: Optional[Any]
|
|
267
|
+
) -> None:
|
|
292
268
|
if value is not None and should_be_treated_as_error(ty, value):
|
|
293
269
|
self.set_status(SPANSTATUS.INTERNAL_ERROR)
|
|
294
270
|
else:
|
|
@@ -303,41 +279,34 @@ class Span:
|
|
|
303
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.
|