-
Notifications
You must be signed in to change notification settings - Fork 620
feat(quart): Add span streaming support to Quart integration #6502
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: py-2514-gate-asgi-values-behind-pii
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
|
|
@@ -9,7 +9,10 @@ | |
| from sentry_sdk.integrations._wsgi_common import _filter_headers | ||
| from sentry_sdk.integrations.asgi import SentryAsgiMiddleware | ||
| from sentry_sdk.scope import should_send_default_pii | ||
| from sentry_sdk.tracing import SOURCE_FOR_STYLE | ||
| from sentry_sdk.traces import SOURCE_FOR_STYLE as SEGMENT_SOURCE_FOR_STYLE | ||
| from sentry_sdk.traces import StreamedSpan, get_current_span | ||
| from sentry_sdk.tracing import SOURCE_FOR_STYLE as TRANSACTION_SOURCE_FOR_STYLE | ||
| from sentry_sdk.tracing_utils import has_span_streaming_enabled | ||
| from sentry_sdk.utils import ( | ||
| capture_internal_exceptions, | ||
| ensure_integration_enabled, | ||
|
|
@@ -144,9 +147,16 @@ def _set_transaction_name_and_source( | |
| "url": request.url_rule.rule, | ||
| "endpoint": request.url_rule.endpoint, | ||
| } | ||
|
|
||
| source = ( | ||
| SEGMENT_SOURCE_FOR_STYLE[transaction_style] | ||
| if has_span_streaming_enabled(sentry_sdk.get_client().options) | ||
| else TRANSACTION_SOURCE_FOR_STYLE[transaction_style] | ||
| ) | ||
|
|
||
| scope.set_transaction_name( | ||
| name_for_style[transaction_style], | ||
| source=SOURCE_FOR_STYLE[transaction_style], | ||
| name=name_for_style[transaction_style], | ||
| source=source, | ||
| ) | ||
| except Exception: | ||
| pass | ||
|
|
@@ -169,6 +179,39 @@ async def _request_websocket_started(app: "Quart", **kwargs: "Any") -> None: | |
| ) | ||
|
|
||
| scope = sentry_sdk.get_isolation_scope() | ||
|
|
||
| if has_span_streaming_enabled(sentry_sdk.get_client().options): | ||
| current_span = get_current_span() | ||
| if type(current_span) is StreamedSpan: | ||
| segment = current_span._segment | ||
|
|
||
| segment.set_attribute("http.request.method", request_websocket.method) | ||
| header_attributes: "dict[str, Any]" = {} | ||
|
|
||
| for header, header_value in _filter_headers( | ||
| dict(request_websocket.headers), use_annotated_value=False | ||
| ).items(): | ||
| header_attributes[f"http.request.header.{header.lower()}"] = ( | ||
| header_value | ||
| ) | ||
|
|
||
| segment.set_attributes(header_attributes) | ||
|
|
||
| if should_send_default_pii(): | ||
| segment.set_attribute("url.full", request_websocket.url) | ||
| segment.set_attribute( | ||
| "url.query", | ||
| request_websocket.query_string.decode("utf-8", errors="replace"), | ||
| ) | ||
|
|
||
| if len(request_websocket.access_route) >= 1: | ||
| segment.set_attribute( | ||
| "client.address", request_websocket.access_route[0] | ||
| ) | ||
| segment.set_attribute( | ||
| "user.ip_address", request_websocket.access_route[0] | ||
| ) | ||
|
Contributor
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. We should also set It's one of the attributes that should be set on all spans, not just the segment, so it should be set on the scope. Maybe extract the code that fetches the user id from def _fetch_user_id() -> None:
if quart_auth is None:
return
user = quart_auth.current_user
if user is None:
return
try:
return quart_auth.current_user._auth_id
except Exception:
return Noneand then here user_id = _fetch_user_id()
if user_id is not None:
sentry_sdk.get_current_scope().set_attribute("user.id", user_id)and in the event processor user_id = _fetch_user_id()
if user_id is not None:
user_info = event.setdefault("user", {})
user_info["id"] = user_id
Contributor
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. Please also add a test for this if there is none. |
||
|
|
||
| evt_processor = _make_request_event_processor(app, request_websocket, integration) | ||
| scope.add_event_processor(evt_processor) | ||
|
|
||
|
|
@@ -194,7 +237,8 @@ def inner(event: "Event", hint: "dict[str, Any]") -> "Event": | |
| request_info["headers"] = _filter_headers(dict(request.headers)) | ||
|
|
||
| if should_send_default_pii(): | ||
| request_info["env"] = {"REMOTE_ADDR": request.access_route[0]} | ||
| if len(request.access_route) >= 1: | ||
| request_info["env"] = {"REMOTE_ADDR": request.access_route[0]} | ||
| _add_user_to_event(event) | ||
|
|
||
| return event | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.