sentry-sdk 2.34.1__py2.py3-none-any.whl → 2.35.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sentry-sdk might be problematic. Click here for more details.
- sentry_sdk/__init__.py +1 -0
- sentry_sdk/ai/utils.py +9 -9
- sentry_sdk/api.py +80 -0
- sentry_sdk/client.py +8 -5
- sentry_sdk/consts.py +135 -10
- sentry_sdk/crons/api.py +5 -0
- sentry_sdk/integrations/anthropic.py +138 -75
- sentry_sdk/integrations/asgi.py +11 -25
- sentry_sdk/integrations/clickhouse_driver.py +33 -13
- sentry_sdk/integrations/django/asgi.py +1 -1
- sentry_sdk/integrations/fastapi.py +1 -7
- sentry_sdk/integrations/gnu_backtrace.py +6 -3
- sentry_sdk/integrations/langchain.py +466 -193
- sentry_sdk/integrations/litestar.py +1 -1
- sentry_sdk/integrations/logging.py +2 -1
- sentry_sdk/integrations/loguru.py +2 -1
- sentry_sdk/integrations/openai.py +8 -2
- sentry_sdk/integrations/openfeature.py +2 -4
- sentry_sdk/integrations/quart.py +1 -1
- sentry_sdk/integrations/starlette.py +1 -5
- sentry_sdk/integrations/starlite.py +1 -1
- sentry_sdk/scope.py +11 -11
- sentry_sdk/tracing.py +118 -25
- sentry_sdk/tracing_utils.py +321 -39
- sentry_sdk/utils.py +22 -1
- {sentry_sdk-2.34.1.dist-info → sentry_sdk-2.35.0.dist-info}/METADATA +1 -1
- {sentry_sdk-2.34.1.dist-info → sentry_sdk-2.35.0.dist-info}/RECORD +31 -31
- {sentry_sdk-2.34.1.dist-info → sentry_sdk-2.35.0.dist-info}/WHEEL +0 -0
- {sentry_sdk-2.34.1.dist-info → sentry_sdk-2.35.0.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-2.34.1.dist-info → sentry_sdk-2.35.0.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-2.34.1.dist-info → sentry_sdk-2.35.0.dist-info}/top_level.txt +0 -0
|
@@ -85,6 +85,7 @@ class SentryLitestarASGIMiddleware(SentryAsgiMiddleware):
|
|
|
85
85
|
transaction_style="endpoint",
|
|
86
86
|
mechanism_type="asgi",
|
|
87
87
|
span_origin=span_origin,
|
|
88
|
+
asgi_version=3,
|
|
88
89
|
)
|
|
89
90
|
|
|
90
91
|
def _capture_request_exception(self, exc):
|
|
@@ -116,7 +117,6 @@ def patch_app_init():
|
|
|
116
117
|
*(kwargs.get("after_exception") or []),
|
|
117
118
|
]
|
|
118
119
|
|
|
119
|
-
SentryLitestarASGIMiddleware.__call__ = SentryLitestarASGIMiddleware._run_asgi3 # type: ignore
|
|
120
120
|
middleware = kwargs.get("middleware") or []
|
|
121
121
|
kwargs["middleware"] = [SentryLitestarASGIMiddleware, *middleware]
|
|
122
122
|
old__init__(self, *args, **kwargs)
|
|
@@ -12,6 +12,7 @@ from sentry_sdk.utils import (
|
|
|
12
12
|
event_from_exception,
|
|
13
13
|
current_stacktrace,
|
|
14
14
|
capture_internal_exceptions,
|
|
15
|
+
has_logs_enabled,
|
|
15
16
|
)
|
|
16
17
|
from sentry_sdk.integrations import Integration
|
|
17
18
|
|
|
@@ -344,7 +345,7 @@ class SentryLogsHandler(_BaseHandler):
|
|
|
344
345
|
if not client.is_active():
|
|
345
346
|
return
|
|
346
347
|
|
|
347
|
-
if not client.options
|
|
348
|
+
if not has_logs_enabled(client.options):
|
|
348
349
|
return
|
|
349
350
|
|
|
350
351
|
self._capture_log_from_record(client, record)
|
|
@@ -8,6 +8,7 @@ from sentry_sdk.integrations.logging import (
|
|
|
8
8
|
_BaseHandler,
|
|
9
9
|
)
|
|
10
10
|
from sentry_sdk.logger import _log_level_to_otel
|
|
11
|
+
from sentry_sdk.utils import has_logs_enabled
|
|
11
12
|
|
|
12
13
|
from typing import TYPE_CHECKING
|
|
13
14
|
|
|
@@ -151,7 +152,7 @@ def loguru_sentry_logs_handler(message):
|
|
|
151
152
|
if not client.is_active():
|
|
152
153
|
return
|
|
153
154
|
|
|
154
|
-
if not client.options
|
|
155
|
+
if not has_logs_enabled(client.options):
|
|
155
156
|
return
|
|
156
157
|
|
|
157
158
|
record = message.record
|
|
@@ -20,6 +20,11 @@ if TYPE_CHECKING:
|
|
|
20
20
|
from sentry_sdk.tracing import Span
|
|
21
21
|
|
|
22
22
|
try:
|
|
23
|
+
try:
|
|
24
|
+
from openai import NOT_GIVEN
|
|
25
|
+
except ImportError:
|
|
26
|
+
NOT_GIVEN = None
|
|
27
|
+
|
|
23
28
|
from openai.resources.chat.completions import Completions, AsyncCompletions
|
|
24
29
|
from openai.resources import Embeddings, AsyncEmbeddings
|
|
25
30
|
|
|
@@ -192,12 +197,13 @@ def _set_input_data(span, kwargs, operation, integration):
|
|
|
192
197
|
}
|
|
193
198
|
for key, attribute in kwargs_keys_to_attributes.items():
|
|
194
199
|
value = kwargs.get(key)
|
|
195
|
-
|
|
200
|
+
|
|
201
|
+
if value is not NOT_GIVEN and value is not None:
|
|
196
202
|
set_data_normalized(span, attribute, value)
|
|
197
203
|
|
|
198
204
|
# Input attributes: Tools
|
|
199
205
|
tools = kwargs.get("tools")
|
|
200
|
-
if tools is not None and len(tools) > 0:
|
|
206
|
+
if tools is not NOT_GIVEN and tools is not None and len(tools) > 0:
|
|
201
207
|
set_data_normalized(
|
|
202
208
|
span, SPANDATA.GEN_AI_REQUEST_AVAILABLE_TOOLS, safe_serialize(tools)
|
|
203
209
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING, Any
|
|
2
2
|
|
|
3
3
|
from sentry_sdk.feature_flags import add_feature_flag
|
|
4
4
|
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
@@ -8,7 +8,6 @@ try:
|
|
|
8
8
|
from openfeature.hook import Hook
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
-
from openfeature.flag_evaluation import FlagEvaluationDetails
|
|
12
11
|
from openfeature.hook import HookContext, HookHints
|
|
13
12
|
except ImportError:
|
|
14
13
|
raise DidNotEnable("OpenFeature is not installed")
|
|
@@ -25,9 +24,8 @@ class OpenFeatureIntegration(Integration):
|
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
class OpenFeatureHook(Hook):
|
|
28
|
-
|
|
29
27
|
def after(self, hook_context, details, hints):
|
|
30
|
-
# type: (
|
|
28
|
+
# type: (Any, Any, Any) -> None
|
|
31
29
|
if isinstance(details.value, bool):
|
|
32
30
|
add_feature_flag(details.flag_key, details.value)
|
|
33
31
|
|
sentry_sdk/integrations/quart.py
CHANGED
|
@@ -95,8 +95,8 @@ def patch_asgi_app():
|
|
|
95
95
|
middleware = SentryAsgiMiddleware(
|
|
96
96
|
lambda *a, **kw: old_app(self, *a, **kw),
|
|
97
97
|
span_origin=QuartIntegration.origin,
|
|
98
|
+
asgi_version=3,
|
|
98
99
|
)
|
|
99
|
-
middleware.__call__ = middleware._run_asgi3
|
|
100
100
|
return await middleware(scope, receive, send)
|
|
101
101
|
|
|
102
102
|
Quart.__call__ = sentry_patched_asgi_app
|
|
@@ -29,7 +29,6 @@ from sentry_sdk.utils import (
|
|
|
29
29
|
capture_internal_exceptions,
|
|
30
30
|
ensure_integration_enabled,
|
|
31
31
|
event_from_exception,
|
|
32
|
-
logger,
|
|
33
32
|
parse_version,
|
|
34
33
|
transaction_from_function,
|
|
35
34
|
)
|
|
@@ -403,9 +402,9 @@ def patch_asgi_app():
|
|
|
403
402
|
if integration
|
|
404
403
|
else DEFAULT_HTTP_METHODS_TO_CAPTURE
|
|
405
404
|
),
|
|
405
|
+
asgi_version=3,
|
|
406
406
|
)
|
|
407
407
|
|
|
408
|
-
middleware.__call__ = middleware._run_asgi3
|
|
409
408
|
return await middleware(scope, receive, send)
|
|
410
409
|
|
|
411
410
|
Starlette.__call__ = _sentry_patched_asgi_app
|
|
@@ -723,9 +722,6 @@ def _set_transaction_name_and_source(scope, transaction_style, request):
|
|
|
723
722
|
source = TransactionSource.ROUTE
|
|
724
723
|
|
|
725
724
|
scope.set_transaction_name(name, source=source)
|
|
726
|
-
logger.debug(
|
|
727
|
-
"[Starlette] Set transaction name and source on scope: %s / %s", name, source
|
|
728
|
-
)
|
|
729
725
|
|
|
730
726
|
|
|
731
727
|
def _get_transaction_from_middleware(app, asgi_scope, integration):
|
|
@@ -65,6 +65,7 @@ class SentryStarliteASGIMiddleware(SentryAsgiMiddleware):
|
|
|
65
65
|
transaction_style="endpoint",
|
|
66
66
|
mechanism_type="asgi",
|
|
67
67
|
span_origin=span_origin,
|
|
68
|
+
asgi_version=3,
|
|
68
69
|
)
|
|
69
70
|
|
|
70
71
|
|
|
@@ -94,7 +95,6 @@ def patch_app_init():
|
|
|
94
95
|
]
|
|
95
96
|
)
|
|
96
97
|
|
|
97
|
-
SentryStarliteASGIMiddleware.__call__ = SentryStarliteASGIMiddleware._run_asgi3 # type: ignore
|
|
98
98
|
middleware = kwargs.get("middleware") or []
|
|
99
99
|
kwargs["middleware"] = [SentryStarliteASGIMiddleware, *middleware]
|
|
100
100
|
old__init__(self, *args, **kwargs)
|
sentry_sdk/scope.py
CHANGED
|
@@ -48,7 +48,7 @@ import typing
|
|
|
48
48
|
from typing import TYPE_CHECKING
|
|
49
49
|
|
|
50
50
|
if TYPE_CHECKING:
|
|
51
|
-
from collections.abc import Mapping
|
|
51
|
+
from collections.abc import Mapping
|
|
52
52
|
|
|
53
53
|
from typing import Any
|
|
54
54
|
from typing import Callable
|
|
@@ -238,24 +238,24 @@ class Scope:
|
|
|
238
238
|
rv._name = self._name
|
|
239
239
|
rv._fingerprint = self._fingerprint
|
|
240
240
|
rv._transaction = self._transaction
|
|
241
|
-
rv._transaction_info =
|
|
241
|
+
rv._transaction_info = self._transaction_info.copy()
|
|
242
242
|
rv._user = self._user
|
|
243
243
|
|
|
244
|
-
rv._tags =
|
|
245
|
-
rv._contexts =
|
|
246
|
-
rv._extras =
|
|
244
|
+
rv._tags = self._tags.copy()
|
|
245
|
+
rv._contexts = self._contexts.copy()
|
|
246
|
+
rv._extras = self._extras.copy()
|
|
247
247
|
|
|
248
248
|
rv._breadcrumbs = copy(self._breadcrumbs)
|
|
249
|
-
rv._n_breadcrumbs_truncated =
|
|
250
|
-
rv._event_processors =
|
|
251
|
-
rv._error_processors =
|
|
249
|
+
rv._n_breadcrumbs_truncated = self._n_breadcrumbs_truncated
|
|
250
|
+
rv._event_processors = self._event_processors.copy()
|
|
251
|
+
rv._error_processors = self._error_processors.copy()
|
|
252
252
|
rv._propagation_context = self._propagation_context
|
|
253
253
|
|
|
254
254
|
rv._should_capture = self._should_capture
|
|
255
255
|
rv._span = self._span
|
|
256
256
|
rv._session = self._session
|
|
257
257
|
rv._force_auto_session_tracking = self._force_auto_session_tracking
|
|
258
|
-
rv._attachments =
|
|
258
|
+
rv._attachments = self._attachments.copy()
|
|
259
259
|
|
|
260
260
|
rv._profile = self._profile
|
|
261
261
|
|
|
@@ -683,12 +683,12 @@ class Scope:
|
|
|
683
683
|
self._level = None # type: Optional[LogLevelStr]
|
|
684
684
|
self._fingerprint = None # type: Optional[List[str]]
|
|
685
685
|
self._transaction = None # type: Optional[str]
|
|
686
|
-
self._transaction_info = {} # type:
|
|
686
|
+
self._transaction_info = {} # type: dict[str, str]
|
|
687
687
|
self._user = None # type: Optional[Dict[str, Any]]
|
|
688
688
|
|
|
689
689
|
self._tags = {} # type: Dict[str, Any]
|
|
690
690
|
self._contexts = {} # type: Dict[str, Dict[str, Any]]
|
|
691
|
-
self._extras = {} # type:
|
|
691
|
+
self._extras = {} # type: dict[str, Any]
|
|
692
692
|
self._attachments = [] # type: List[Attachment]
|
|
693
693
|
|
|
694
694
|
self.clear_breadcrumbs()
|
sentry_sdk/tracing.py
CHANGED
|
@@ -5,7 +5,7 @@ from datetime import datetime, timedelta, timezone
|
|
|
5
5
|
from enum import Enum
|
|
6
6
|
|
|
7
7
|
import sentry_sdk
|
|
8
|
-
from sentry_sdk.consts import INSTRUMENTER, SPANSTATUS, SPANDATA
|
|
8
|
+
from sentry_sdk.consts import INSTRUMENTER, SPANSTATUS, SPANDATA, SPANTEMPLATE
|
|
9
9
|
from sentry_sdk.profiler.continuous_profiler import get_profiler_id
|
|
10
10
|
from sentry_sdk.utils import (
|
|
11
11
|
get_current_thread_meta,
|
|
@@ -257,8 +257,8 @@ class Span:
|
|
|
257
257
|
"""
|
|
258
258
|
|
|
259
259
|
__slots__ = (
|
|
260
|
-
"
|
|
261
|
-
"
|
|
260
|
+
"_trace_id",
|
|
261
|
+
"_span_id",
|
|
262
262
|
"parent_span_id",
|
|
263
263
|
"same_process_as_parent",
|
|
264
264
|
"sampled",
|
|
@@ -301,8 +301,8 @@ class Span:
|
|
|
301
301
|
name=None, # type: Optional[str]
|
|
302
302
|
):
|
|
303
303
|
# type: (...) -> None
|
|
304
|
-
self.
|
|
305
|
-
self.
|
|
304
|
+
self._trace_id = trace_id
|
|
305
|
+
self._span_id = span_id
|
|
306
306
|
self.parent_span_id = parent_span_id
|
|
307
307
|
self.same_process_as_parent = same_process_as_parent
|
|
308
308
|
self.sampled = sampled
|
|
@@ -356,6 +356,32 @@ class Span:
|
|
|
356
356
|
if self._span_recorder is None:
|
|
357
357
|
self._span_recorder = _SpanRecorder(maxlen)
|
|
358
358
|
|
|
359
|
+
@property
|
|
360
|
+
def trace_id(self):
|
|
361
|
+
# type: () -> str
|
|
362
|
+
if not self._trace_id:
|
|
363
|
+
self._trace_id = uuid.uuid4().hex
|
|
364
|
+
|
|
365
|
+
return self._trace_id
|
|
366
|
+
|
|
367
|
+
@trace_id.setter
|
|
368
|
+
def trace_id(self, value):
|
|
369
|
+
# type: (str) -> None
|
|
370
|
+
self._trace_id = value
|
|
371
|
+
|
|
372
|
+
@property
|
|
373
|
+
def span_id(self):
|
|
374
|
+
# type: () -> str
|
|
375
|
+
if not self._span_id:
|
|
376
|
+
self._span_id = uuid.uuid4().hex[16:]
|
|
377
|
+
|
|
378
|
+
return self._span_id
|
|
379
|
+
|
|
380
|
+
@span_id.setter
|
|
381
|
+
def span_id(self, value):
|
|
382
|
+
# type: (str) -> None
|
|
383
|
+
self._span_id = value
|
|
384
|
+
|
|
359
385
|
def _get_local_aggregator(self):
|
|
360
386
|
# type: (...) -> LocalAggregator
|
|
361
387
|
rv = self._local_aggregator
|
|
@@ -602,6 +628,10 @@ class Span:
|
|
|
602
628
|
# type: (str, Any) -> None
|
|
603
629
|
self._data[key] = value
|
|
604
630
|
|
|
631
|
+
def update_data(self, data):
|
|
632
|
+
# type: (Dict[str, Any]) -> None
|
|
633
|
+
self._data.update(data)
|
|
634
|
+
|
|
605
635
|
def set_flag(self, flag, result):
|
|
606
636
|
# type: (str, bool) -> None
|
|
607
637
|
if len(self._flags) < self._flags_capacity:
|
|
@@ -818,7 +848,6 @@ class Transaction(Span):
|
|
|
818
848
|
**kwargs, # type: Unpack[SpanKwargs]
|
|
819
849
|
):
|
|
820
850
|
# type: (...) -> None
|
|
821
|
-
|
|
822
851
|
super().__init__(**kwargs)
|
|
823
852
|
|
|
824
853
|
self.name = name
|
|
@@ -1275,6 +1304,10 @@ class NoOpSpan(Span):
|
|
|
1275
1304
|
# type: (str, Any) -> None
|
|
1276
1305
|
pass
|
|
1277
1306
|
|
|
1307
|
+
def update_data(self, data):
|
|
1308
|
+
# type: (Dict[str, Any]) -> None
|
|
1309
|
+
pass
|
|
1310
|
+
|
|
1278
1311
|
def set_status(self, value):
|
|
1279
1312
|
# type: (str) -> None
|
|
1280
1313
|
pass
|
|
@@ -1332,43 +1365,103 @@ class NoOpSpan(Span):
|
|
|
1332
1365
|
if TYPE_CHECKING:
|
|
1333
1366
|
|
|
1334
1367
|
@overload
|
|
1335
|
-
def trace(
|
|
1336
|
-
|
|
1368
|
+
def trace(
|
|
1369
|
+
func=None, *, op=None, name=None, attributes=None, template=SPANTEMPLATE.DEFAULT
|
|
1370
|
+
):
|
|
1371
|
+
# type: (None, Optional[str], Optional[str], Optional[dict[str, Any]], SPANTEMPLATE) -> Callable[[Callable[P, R]], Callable[P, R]]
|
|
1372
|
+
# Handles: @trace() and @trace(op="custom")
|
|
1337
1373
|
pass
|
|
1338
1374
|
|
|
1339
1375
|
@overload
|
|
1340
1376
|
def trace(func):
|
|
1341
1377
|
# type: (Callable[P, R]) -> Callable[P, R]
|
|
1378
|
+
# Handles: @trace
|
|
1342
1379
|
pass
|
|
1343
1380
|
|
|
1344
1381
|
|
|
1345
|
-
def trace(
|
|
1346
|
-
|
|
1382
|
+
def trace(
|
|
1383
|
+
func=None, *, op=None, name=None, attributes=None, template=SPANTEMPLATE.DEFAULT
|
|
1384
|
+
):
|
|
1385
|
+
# type: (Optional[Callable[P, R]], Optional[str], Optional[str], Optional[dict[str, Any]], SPANTEMPLATE) -> Union[Callable[P, R], Callable[[Callable[P, R]], Callable[P, R]]]
|
|
1347
1386
|
"""
|
|
1348
|
-
Decorator to start a child span
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1387
|
+
Decorator to start a child span around a function call.
|
|
1388
|
+
|
|
1389
|
+
This decorator automatically creates a new span when the decorated function
|
|
1390
|
+
is called, and finishes the span when the function returns or raises an exception.
|
|
1391
|
+
|
|
1392
|
+
:param func: The function to trace. When used as a decorator without parentheses,
|
|
1393
|
+
this is the function being decorated. When used with parameters (e.g.,
|
|
1394
|
+
``@trace(op="custom")``, this should be None.
|
|
1395
|
+
:type func: Callable or None
|
|
1396
|
+
|
|
1397
|
+
:param op: The operation name for the span. This is a high-level description
|
|
1398
|
+
of what the span represents (e.g., "http.client", "db.query").
|
|
1399
|
+
You can use predefined constants from :py:class:`sentry_sdk.consts.OP`
|
|
1400
|
+
or provide your own string. If not provided, a default operation will
|
|
1401
|
+
be assigned based on the template.
|
|
1402
|
+
:type op: str or None
|
|
1403
|
+
|
|
1404
|
+
:param name: The human-readable name/description for the span. If not provided,
|
|
1405
|
+
defaults to the function name. This provides more specific details about
|
|
1406
|
+
what the span represents (e.g., "GET /api/users", "process_user_data").
|
|
1407
|
+
:type name: str or None
|
|
1408
|
+
|
|
1409
|
+
:param attributes: A dictionary of key-value pairs to add as attributes to the span.
|
|
1410
|
+
Attribute values must be strings, integers, floats, or booleans. These
|
|
1411
|
+
attributes provide additional context about the span's execution.
|
|
1412
|
+
:type attributes: dict[str, Any] or None
|
|
1413
|
+
|
|
1414
|
+
:param template: The type of span to create. This determines what kind of
|
|
1415
|
+
span instrumentation and data collection will be applied. Use predefined
|
|
1416
|
+
constants from :py:class:`sentry_sdk.consts.SPANTEMPLATE`.
|
|
1417
|
+
The default is `SPANTEMPLATE.DEFAULT` which is the right choice for most
|
|
1418
|
+
use cases.
|
|
1419
|
+
:type template: :py:class:`sentry_sdk.consts.SPANTEMPLATE`
|
|
1420
|
+
|
|
1421
|
+
:returns: When used as ``@trace``, returns the decorated function. When used as
|
|
1422
|
+
``@trace(...)`` with parameters, returns a decorator function.
|
|
1423
|
+
:rtype: Callable or decorator function
|
|
1424
|
+
|
|
1425
|
+
Example::
|
|
1353
1426
|
|
|
1354
1427
|
import sentry_sdk
|
|
1428
|
+
from sentry_sdk.consts import OP, SPANTEMPLATE
|
|
1355
1429
|
|
|
1430
|
+
# Simple usage with default values
|
|
1356
1431
|
@sentry_sdk.trace
|
|
1357
|
-
def
|
|
1358
|
-
|
|
1432
|
+
def process_data():
|
|
1433
|
+
# Function implementation
|
|
1434
|
+
pass
|
|
1359
1435
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1436
|
+
# With custom parameters
|
|
1437
|
+
@sentry_sdk.trace(
|
|
1438
|
+
op=OP.DB_QUERY,
|
|
1439
|
+
name="Get user data",
|
|
1440
|
+
attributes={"postgres": True}
|
|
1441
|
+
)
|
|
1442
|
+
def make_db_query(sql):
|
|
1443
|
+
# Function implementation
|
|
1444
|
+
pass
|
|
1445
|
+
|
|
1446
|
+
# With a custom template
|
|
1447
|
+
@sentry_sdk.trace(template=SPANTEMPLATE.AI_TOOL)
|
|
1448
|
+
def calculate_interest_rate(amount, rate, years):
|
|
1449
|
+
# Function implementation
|
|
1450
|
+
pass
|
|
1363
1451
|
"""
|
|
1364
|
-
from sentry_sdk.tracing_utils import
|
|
1452
|
+
from sentry_sdk.tracing_utils import create_span_decorator
|
|
1453
|
+
|
|
1454
|
+
decorator = create_span_decorator(
|
|
1455
|
+
op=op,
|
|
1456
|
+
name=name,
|
|
1457
|
+
attributes=attributes,
|
|
1458
|
+
template=template,
|
|
1459
|
+
)
|
|
1365
1460
|
|
|
1366
|
-
# This patterns allows usage of both @sentry_traced and @sentry_traced(...)
|
|
1367
|
-
# See https://stackoverflow.com/questions/52126071/decorator-with-arguments-avoid-parenthesis-when-no-arguments/52126278
|
|
1368
1461
|
if func:
|
|
1369
|
-
return
|
|
1462
|
+
return decorator(func)
|
|
1370
1463
|
else:
|
|
1371
|
-
return
|
|
1464
|
+
return decorator
|
|
1372
1465
|
|
|
1373
1466
|
|
|
1374
1467
|
# Circular imports
|