-
Notifications
You must be signed in to change notification settings - Fork 602
feat(asgi): Migrate away from event processor in span first #5920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
282ba35
e2484bd
51af434
5c3174f
b270e5a
e93fd1b
7cde973
ef9e640
df3f3af
babb3bd
75429dc
d9d7674
32e4191
5cecf97
a39337b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,6 +12,7 @@ | |||||||||
| from typing import Union | ||||||||||
| from typing_extensions import Literal | ||||||||||
|
|
||||||||||
| from sentry_sdk._types import Attributes | ||||||||||
| from sentry_sdk.utils import AnnotatedValue | ||||||||||
|
|
||||||||||
|
|
||||||||||
|
|
@@ -105,3 +106,31 @@ | |||||||||
| request_data["env"] = {"REMOTE_ADDR": _get_ip(asgi_scope)} | ||||||||||
|
|
||||||||||
| return request_data | ||||||||||
|
|
||||||||||
|
|
||||||||||
| def _get_request_attributes(asgi_scope: "Any") -> "dict[str, Any]": | ||||||||||
| """ | ||||||||||
| Return attributes related to the HTTP request from the ASGI scope. | ||||||||||
| """ | ||||||||||
| attributes: "Attributes" = {} | ||||||||||
|
|
||||||||||
| ty = asgi_scope["type"] | ||||||||||
| if ty in ("http", "websocket"): | ||||||||||
| if asgi_scope.get("method"): | ||||||||||
| attributes["http.request.method"] = asgi_scope["method"].upper() | ||||||||||
|
|
||||||||||
| headers = _filter_headers(_get_headers(asgi_scope), use_annotated_value=False) | ||||||||||
| for header, value in headers.items(): | ||||||||||
| attributes[f"http.request.header.{header.lower()}"] = value | ||||||||||
sentry-warden[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| attributes["http.query"] = _get_query(asgi_scope) | ||||||||||
|
Check warning on line 126 in sentry_sdk/integrations/_asgi_common.py
|
||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. http.query attribute set to string "None" when no query string present When there's no query string in the request, VerificationVerified by reading Suggested fix: Only set the http.query attribute when a query string is present
Suggested change
Identified by Warden |
||||||||||
|
|
||||||||||
| attributes["url.full"] = _get_url( | ||||||||||
| asgi_scope, "http" if ty == "http" else "ws", headers.get("host") | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| client = asgi_scope.get("client") | ||||||||||
| if client and should_send_default_pii(): | ||||||||||
| attributes["client.address"] = _get_ip(asgi_scope) | ||||||||||
|
|
||||||||||
| return attributes | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
| from sentry_sdk.consts import OP | ||
| from sentry_sdk.integrations._asgi_common import ( | ||
| _get_headers, | ||
| _get_request_attributes, | ||
| _get_request_data, | ||
| _get_url, | ||
| ) | ||
|
|
@@ -23,7 +24,11 @@ | |
| nullcontext, | ||
| ) | ||
| from sentry_sdk.sessions import track_session | ||
| from sentry_sdk.traces import StreamedSpan | ||
| from sentry_sdk.traces import ( | ||
| StreamedSpan, | ||
| SegmentSource, | ||
| SOURCE_FOR_STYLE as SEGMENT_SOURCE_FOR_STYLE, | ||
| ) | ||
| from sentry_sdk.tracing import ( | ||
| SOURCE_FOR_STYLE, | ||
| Transaction, | ||
|
|
@@ -40,6 +45,7 @@ | |
| _get_installed_modules, | ||
| reraise, | ||
| capture_internal_exceptions, | ||
| qualname_from_function, | ||
| ) | ||
|
|
||
| from typing import TYPE_CHECKING | ||
|
|
@@ -235,7 +241,7 @@ | |
| transaction_source, "value", transaction_source | ||
| ), | ||
| "sentry.origin": self.span_origin, | ||
| "asgi.type": ty, | ||
| "network.protocol.name": ty, | ||
sentry-warden[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| if ty in ("http", "websocket"): | ||
|
|
@@ -301,6 +307,9 @@ | |
| else nullcontext() | ||
| ) | ||
|
|
||
| for attribute, value in _get_request_attributes(scope).items(): | ||
| sentry_scope.set_attribute(attribute, value) | ||
|
|
||
| with span_ctx as span: | ||
| try: | ||
|
|
||
|
|
@@ -336,6 +345,7 @@ | |
| return await self.app( | ||
| scope, receive, _sentry_wrapped_send | ||
| ) | ||
|
|
||
| except Exception as exc: | ||
| suppress_chained_exceptions = ( | ||
| sentry_sdk.get_client() | ||
|
|
@@ -350,6 +360,15 @@ | |
| with capture_internal_exceptions(): | ||
| self._capture_request_exception(exc) | ||
| reraise(*exc_info) | ||
|
|
||
| finally: | ||
| with capture_internal_exceptions(): | ||
| name, source = self._get_segment_name_and_source( | ||
| self.transaction_style, scope | ||
| ) | ||
| if isinstance(span, StreamedSpan): | ||
| span.name = name | ||
| span.set_attribute("sentry.span.source", source) | ||
|
Check warning on line 371 in sentry_sdk/integrations/asgi.py
|
||
| finally: | ||
| _asgi_middleware_applied.set(False) | ||
|
|
||
|
|
@@ -424,3 +443,40 @@ | |
| return name, source | ||
|
|
||
| return name, source | ||
|
|
||
| def _get_segment_name_and_source( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a copy of |
||
| self: "SentryAsgiMiddleware", segment_style: str, asgi_scope: "Any" | ||
| ) -> "Tuple[str, str]": | ||
| name = None | ||
| source = SEGMENT_SOURCE_FOR_STYLE[segment_style].value | ||
| ty = asgi_scope.get("type") | ||
|
|
||
| if segment_style == "endpoint": | ||
| endpoint = asgi_scope.get("endpoint") | ||
| # Webframeworks like Starlette mutate the ASGI env once routing is | ||
| # done, which is sometime after the request has started. If we have | ||
| # an endpoint, overwrite our generic transaction name. | ||
| if endpoint: | ||
| name = qualname_from_function(endpoint) or "" | ||
| else: | ||
| name = _get_url(asgi_scope, "http" if ty == "http" else "ws", host=None) | ||
| source = SegmentSource.URL.value | ||
|
|
||
| elif segment_style == "url": | ||
| # FastAPI includes the route object in the scope to let Sentry extract the | ||
| # path from it for the transaction name | ||
| route = asgi_scope.get("route") | ||
| if route: | ||
| path = getattr(route, "path", None) | ||
| if path is not None: | ||
| name = path | ||
| else: | ||
| name = _get_url(asgi_scope, "http" if ty == "http" else "ws", host=None) | ||
| source = SegmentSource.URL.value | ||
|
|
||
| if name is None: | ||
| name = _DEFAULT_TRANSACTION_NAME | ||
| source = SegmentSource.ROUTE.value | ||
| return name, source | ||
|
|
||
| return name, source | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an attributes based copy of
_get_request_datajust above