diff --git a/sentry_sdk/integrations/asgi.py b/sentry_sdk/integrations/asgi.py index 1b020ebbc0..dde8128a33 100644 --- a/sentry_sdk/integrations/asgi.py +++ b/sentry_sdk/integrations/asgi.py @@ -12,7 +12,6 @@ import sentry_sdk from sentry_sdk.api import continue_trace from sentry_sdk.consts import OP - from sentry_sdk.integrations._asgi_common import ( _get_headers, _get_request_data, @@ -42,7 +41,6 @@ if TYPE_CHECKING: from typing import Any - from typing import Callable from typing import Dict from typing import Optional from typing import Tuple @@ -102,6 +100,7 @@ def __init__( mechanism_type="asgi", # type: str span_origin="manual", # type: str http_methods_to_capture=DEFAULT_HTTP_METHODS_TO_CAPTURE, # type: Tuple[str, ...] + asgi_version=None, # type: Optional[int] ): # type: (...) -> None """ @@ -140,10 +139,16 @@ def __init__( self.app = app self.http_methods_to_capture = http_methods_to_capture - if _looks_like_asgi3(app): - self.__call__ = self._run_asgi3 # type: Callable[..., Any] - else: - self.__call__ = self._run_asgi2 + if asgi_version is None: + if _looks_like_asgi3(app): + asgi_version = 3 + else: + asgi_version = 2 + + if asgi_version == 3: + self.__call__ = self._run_asgi3 + elif asgi_version == 2: + self.__call__ = self._run_asgi2 # type: ignore def _capture_lifespan_exception(self, exc): # type: (Exception) -> None @@ -217,10 +222,6 @@ async def _run_app(self, scope, receive, send, asgi_version): source=transaction_source, origin=self.span_origin, ) - logger.debug( - "[ASGI] Created transaction (continuing trace): %s", - transaction, - ) else: transaction = Transaction( op=OP.HTTP_SERVER, @@ -228,17 +229,9 @@ async def _run_app(self, scope, receive, send, asgi_version): source=transaction_source, origin=self.span_origin, ) - logger.debug( - "[ASGI] Created transaction (new): %s", transaction - ) if transaction: transaction.set_tag("asgi.type", ty) - logger.debug( - "[ASGI] Set transaction name and source on transaction: '%s' / '%s'", - transaction.name, - transaction.source, - ) with ( sentry_sdk.start_transaction( @@ -248,7 +241,6 @@ async def _run_app(self, scope, receive, send, asgi_version): if transaction is not None else nullcontext() ): - logger.debug("[ASGI] Started transaction: %s", transaction) try: async def _sentry_wrapped_send(event): @@ -303,12 +295,6 @@ def event_processor(self, event, hint, asgi_scope): event["transaction"] = name event["transaction_info"] = {"source": source} - logger.debug( - "[ASGI] Set transaction name and source in event_processor: '%s' / '%s'", - event["transaction"], - event["transaction_info"]["source"], - ) - return event # Helper functions. diff --git a/sentry_sdk/integrations/django/asgi.py b/sentry_sdk/integrations/django/asgi.py index 63a3f0b8f2..773c538045 100644 --- a/sentry_sdk/integrations/django/asgi.py +++ b/sentry_sdk/integrations/django/asgi.py @@ -155,7 +155,7 @@ async def sentry_patched_asgi_handler(self, receive, send): http_methods_to_capture=integration.http_methods_to_capture, ) - return await middleware(self.scope)(receive, send) + return await middleware(self.scope)(receive, send) # type: ignore cls.__call__ = sentry_patched_asgi_handler diff --git a/sentry_sdk/integrations/fastapi.py b/sentry_sdk/integrations/fastapi.py index 76c6adee0f..1473cbcab7 100644 --- a/sentry_sdk/integrations/fastapi.py +++ b/sentry_sdk/integrations/fastapi.py @@ -6,10 +6,7 @@ from sentry_sdk.integrations import DidNotEnable from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import SOURCE_FOR_STYLE, TransactionSource -from sentry_sdk.utils import ( - transaction_from_function, - logger, -) +from sentry_sdk.utils import transaction_from_function from typing import TYPE_CHECKING @@ -66,9 +63,6 @@ def _set_transaction_name_and_source(scope, transaction_style, request): source = SOURCE_FOR_STYLE[transaction_style] scope.set_transaction_name(name, source=source) - logger.debug( - "[FastAPI] Set transaction name and source on scope: %s / %s", name, source - ) def patch_get_request_handler(): diff --git a/sentry_sdk/integrations/litestar.py b/sentry_sdk/integrations/litestar.py index 4e15081cba..2be4d376e0 100644 --- a/sentry_sdk/integrations/litestar.py +++ b/sentry_sdk/integrations/litestar.py @@ -85,6 +85,7 @@ def __init__(self, app, span_origin=LitestarIntegration.origin): transaction_style="endpoint", mechanism_type="asgi", span_origin=span_origin, + asgi_version=3, ) def _capture_request_exception(self, exc): @@ -116,7 +117,6 @@ def injection_wrapper(self, *args, **kwargs): *(kwargs.get("after_exception") or []), ] - SentryLitestarASGIMiddleware.__call__ = SentryLitestarASGIMiddleware._run_asgi3 # type: ignore middleware = kwargs.get("middleware") or [] kwargs["middleware"] = [SentryLitestarASGIMiddleware, *middleware] old__init__(self, *args, **kwargs) diff --git a/sentry_sdk/integrations/quart.py b/sentry_sdk/integrations/quart.py index 51306bb4cd..64f7e0bcd2 100644 --- a/sentry_sdk/integrations/quart.py +++ b/sentry_sdk/integrations/quart.py @@ -95,8 +95,8 @@ async def sentry_patched_asgi_app(self, scope, receive, send): middleware = SentryAsgiMiddleware( lambda *a, **kw: old_app(self, *a, **kw), span_origin=QuartIntegration.origin, + asgi_version=3, ) - middleware.__call__ = middleware._run_asgi3 return await middleware(scope, receive, send) Quart.__call__ = sentry_patched_asgi_app diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index d0f0bf2045..c7ce40618b 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -29,7 +29,6 @@ capture_internal_exceptions, ensure_integration_enabled, event_from_exception, - logger, parse_version, transaction_from_function, ) @@ -403,9 +402,9 @@ async def _sentry_patched_asgi_app(self, scope, receive, send): if integration else DEFAULT_HTTP_METHODS_TO_CAPTURE ), + asgi_version=3, ) - middleware.__call__ = middleware._run_asgi3 return await middleware(scope, receive, send) Starlette.__call__ = _sentry_patched_asgi_app @@ -723,9 +722,6 @@ def _set_transaction_name_and_source(scope, transaction_style, request): source = TransactionSource.ROUTE scope.set_transaction_name(name, source=source) - logger.debug( - "[Starlette] Set transaction name and source on scope: %s / %s", name, source - ) def _get_transaction_from_middleware(app, asgi_scope, integration): diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 24707a18b1..b402aa2184 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -65,6 +65,7 @@ def __init__(self, app, span_origin=StarliteIntegration.origin): transaction_style="endpoint", mechanism_type="asgi", span_origin=span_origin, + asgi_version=3, ) @@ -94,7 +95,6 @@ def injection_wrapper(self, *args, **kwargs): ] ) - SentryStarliteASGIMiddleware.__call__ = SentryStarliteASGIMiddleware._run_asgi3 # type: ignore middleware = kwargs.get("middleware") or [] kwargs["middleware"] = [SentryStarliteASGIMiddleware, *middleware] old__init__(self, *args, **kwargs) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 73bf43573e..3356de57a8 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -48,7 +48,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from collections.abc import Mapping, MutableMapping + from collections.abc import Mapping from typing import Any from typing import Callable @@ -238,24 +238,24 @@ def __copy__(self): rv._name = self._name rv._fingerprint = self._fingerprint rv._transaction = self._transaction - rv._transaction_info = dict(self._transaction_info) + rv._transaction_info = self._transaction_info.copy() rv._user = self._user - rv._tags = dict(self._tags) - rv._contexts = dict(self._contexts) - rv._extras = dict(self._extras) + rv._tags = self._tags.copy() + rv._contexts = self._contexts.copy() + rv._extras = self._extras.copy() rv._breadcrumbs = copy(self._breadcrumbs) - rv._n_breadcrumbs_truncated = copy(self._n_breadcrumbs_truncated) - rv._event_processors = list(self._event_processors) - rv._error_processors = list(self._error_processors) + rv._n_breadcrumbs_truncated = self._n_breadcrumbs_truncated + rv._event_processors = self._event_processors.copy() + rv._error_processors = self._error_processors.copy() rv._propagation_context = self._propagation_context rv._should_capture = self._should_capture rv._span = self._span rv._session = self._session rv._force_auto_session_tracking = self._force_auto_session_tracking - rv._attachments = list(self._attachments) + rv._attachments = self._attachments.copy() rv._profile = self._profile @@ -683,12 +683,12 @@ def clear(self): self._level = None # type: Optional[LogLevelStr] self._fingerprint = None # type: Optional[List[str]] self._transaction = None # type: Optional[str] - self._transaction_info = {} # type: MutableMapping[str, str] + self._transaction_info = {} # type: dict[str, str] self._user = None # type: Optional[Dict[str, Any]] self._tags = {} # type: Dict[str, Any] self._contexts = {} # type: Dict[str, Dict[str, Any]] - self._extras = {} # type: MutableMapping[str, Any] + self._extras = {} # type: dict[str, Any] self._attachments = [] # type: List[Attachment] self.clear_breadcrumbs() diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index e9d726cc66..92f7ae2073 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -257,8 +257,8 @@ class Span: """ __slots__ = ( - "trace_id", - "span_id", + "_trace_id", + "_span_id", "parent_span_id", "same_process_as_parent", "sampled", @@ -301,8 +301,8 @@ def __init__( name=None, # type: Optional[str] ): # type: (...) -> None - self.trace_id = trace_id or uuid.uuid4().hex - self.span_id = span_id or uuid.uuid4().hex[16:] + self._trace_id = trace_id + self._span_id = span_id self.parent_span_id = parent_span_id self.same_process_as_parent = same_process_as_parent self.sampled = sampled @@ -356,6 +356,32 @@ def init_span_recorder(self, maxlen): if self._span_recorder is None: self._span_recorder = _SpanRecorder(maxlen) + @property + def trace_id(self): + # type: () -> str + if not self._trace_id: + self._trace_id = uuid.uuid4().hex + + return self._trace_id + + @trace_id.setter + def trace_id(self, value): + # type: (str) -> None + self._trace_id = value + + @property + def span_id(self): + # type: () -> str + if not self._span_id: + self._span_id = uuid.uuid4().hex[16:] + + return self._span_id + + @span_id.setter + def span_id(self, value): + # type: (str) -> None + self._span_id = value + def _get_local_aggregator(self): # type: (...) -> LocalAggregator rv = self._local_aggregator @@ -822,7 +848,6 @@ def __init__( # type: ignore[misc] **kwargs, # type: Unpack[SpanKwargs] ): # type: (...) -> None - super().__init__(**kwargs) self.name = name