Skip to content
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

Use new scopes default integrations. #2856

Merged
64 changes: 30 additions & 34 deletions sentry_sdk/integrations/aiohttp.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import sys
import weakref

import sentry_sdk
from sentry_sdk.api import continue_trace
from sentry_sdk.consts import OP, SPANDATA
from sentry_sdk.hub import Hub
from sentry_sdk.integrations import Integration, DidNotEnable
from sentry_sdk.integrations.logging import ignore_logger
from sentry_sdk.scope import Scope
from sentry_sdk.sessions import auto_session_tracking
from sentry_sdk.sessions import auto_session_tracking_scope
from sentry_sdk.integrations._wsgi_common import (
_filter_headers,
request_body_within_bounds,
Expand All @@ -20,6 +20,8 @@
from sentry_sdk.tracing_utils import should_propagate_trace
from sentry_sdk.utils import (
capture_internal_exceptions,
ensure_integration_enabled,
ensure_integration_enabled_async,
event_from_exception,
logger,
parse_url,
Expand Down Expand Up @@ -96,21 +98,18 @@

old_handle = Application._handle

@ensure_integration_enabled_async(AioHttpIntegration, old_handle)
async def sentry_app_handle(self, request, *args, **kwargs):
# type: (Any, Request, *Any, **Any) -> Any
hub = Hub.current
if hub.get_integration(AioHttpIntegration) is None:
return await old_handle(self, request, *args, **kwargs)

weak_request = weakref.ref(request)

with Hub(hub) as hub:
with auto_session_tracking(hub, session_mode="request"):
with sentry_sdk.isolation_scope() as scope:
with auto_session_tracking_scope(scope, session_mode="request"):
# Scope data will not leak between requests because aiohttp
# create a task to wrap each request.
with hub.configure_scope() as scope:
scope.clear_breadcrumbs()
scope.add_event_processor(_make_request_processor(weak_request))
scope.generate_propagation_context()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you mentioned this, but why is this necessary again?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it is, but it's a direct translation to what the configure_scope was doing in the background:

def configure_scope( # noqa
self,
callback=None, # type: Optional[Callable[[Scope], None]]
continue_trace=True, # type: bool
):
# type: (...) -> Optional[ContextManager[Scope]]
"""
.. deprecated:: 2.0.0
This function is deprecated and will be removed in a future release.
Reconfigures the scope.
:param callback: If provided, call the callback with the current scope.
:returns: If no callback is provided, returns a context manager that returns the scope.
"""
scope = Scope.get_isolation_scope()
if continue_trace:
scope.generate_propagation_context()
if callback is not None:
# TODO: used to return None when client is None. Check if this changes behavior.
callback(scope)
return None

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thanks!

scope.clear_breadcrumbs()
scope.add_event_processor(_make_request_processor(weak_request))

Check warning on line 112 in sentry_sdk/integrations/aiohttp.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/integrations/aiohttp.py#L110-L112

Added lines #L110 - L112 were not covered by tests

headers = dict(request.headers)
transaction = continue_trace(
Expand All @@ -121,7 +120,7 @@
name="generic AIOHTTP request",
source=TRANSACTION_SOURCE_ROUTE,
)
with hub.start_transaction(
with sentry_sdk.start_transaction(
transaction,
custom_sampling_context={"aiohttp_request": request},
):
Expand All @@ -136,7 +135,7 @@
except Exception:
# This will probably map to a 500 but seems like we
# have no way to tell. Do not set span status.
reraise(*_capture_exception(hub))
reraise(*_capture_exception())

Check warning on line 138 in sentry_sdk/integrations/aiohttp.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/integrations/aiohttp.py#L138

Added line #L138 was not covered by tests

transaction.set_http_status(response.status)
return response
Expand All @@ -149,8 +148,7 @@
# type: (UrlDispatcher, Request) -> UrlMappingMatchInfo
rv = await old_urldispatcher_resolve(self, request)

hub = Hub.current
integration = hub.get_integration(AioHttpIntegration)
integration = sentry_sdk.get_client().get_integration(AioHttpIntegration)

Check warning on line 151 in sentry_sdk/integrations/aiohttp.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/integrations/aiohttp.py#L151

Added line #L151 was not covered by tests

name = None

Expand All @@ -176,12 +174,9 @@

old_client_session_init = ClientSession.__init__

@ensure_integration_enabled(AioHttpIntegration, old_client_session_init)
def init(*args, **kwargs):
# type: (Any, Any) -> None
hub = Hub.current
if hub.get_integration(AioHttpIntegration) is None:
return old_client_session_init(*args, **kwargs)

client_trace_configs = list(kwargs.get("trace_configs") or ())
trace_config = create_trace_config()
client_trace_configs.append(trace_config)
Expand All @@ -194,10 +189,11 @@

def create_trace_config():
# type: () -> TraceConfig

async def on_request_start(session, trace_config_ctx, params):
# type: (ClientSession, SimpleNamespace, TraceRequestStartParams) -> None
hub = Hub.current
if hub.get_integration(AioHttpIntegration) is None:
client = sentry_sdk.get_client()

Check warning on line 195 in sentry_sdk/integrations/aiohttp.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/integrations/aiohttp.py#L195

Added line #L195 was not covered by tests
if client.get_integration(AioHttpIntegration) is None:
return

method = params.method.upper()
Expand All @@ -206,7 +202,7 @@
with capture_internal_exceptions():
parsed_url = parse_url(str(params.url), sanitize=False)

span = hub.start_span(
span = sentry_sdk.start_span(

Check warning on line 205 in sentry_sdk/integrations/aiohttp.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/integrations/aiohttp.py#L205

Added line #L205 was not covered by tests
op=OP.HTTP_CLIENT,
description="%s %s"
% (method, parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE),
Expand All @@ -217,8 +213,10 @@
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)

if should_propagate_trace(hub, str(params.url)):
for key, value in hub.iter_trace_propagation_headers(span):
if should_propagate_trace(client, str(params.url)):
for key, value in Scope.get_current_scope().iter_trace_propagation_headers(
span=span
):
logger.debug(
"[Tracing] Adding `{key}` header {value} to outgoing request to {url}.".format(
key=key, value=value, url=params.url
Expand Down Expand Up @@ -275,42 +273,40 @@
request_info["query_string"] = request.query_string
request_info["method"] = request.method
request_info["env"] = {"REMOTE_ADDR": request.remote}

hub = Hub.current
request_info["headers"] = _filter_headers(dict(request.headers))

# Just attach raw data here if it is within bounds, if available.
# Unfortunately there's no way to get structured data from aiohttp
# without awaiting on some coroutine.
request_info["data"] = get_aiohttp_request_data(hub, request)
request_info["data"] = get_aiohttp_request_data(request)

Check warning on line 281 in sentry_sdk/integrations/aiohttp.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/integrations/aiohttp.py#L281

Added line #L281 was not covered by tests

return event

return aiohttp_processor


def _capture_exception(hub):
# type: (Hub) -> ExcInfo
def _capture_exception():
# type: () -> ExcInfo
exc_info = sys.exc_info()
event, hint = event_from_exception(
exc_info,
client_options=hub.client.options, # type: ignore
client_options=sentry_sdk.get_client().options,
mechanism={"type": "aiohttp", "handled": False},
)
hub.capture_event(event, hint=hint)
sentry_sdk.capture_event(event, hint=hint)

Check warning on line 296 in sentry_sdk/integrations/aiohttp.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/integrations/aiohttp.py#L296

Added line #L296 was not covered by tests
return exc_info


BODY_NOT_READ_MESSAGE = "[Can't show request body due to implementation details.]"


def get_aiohttp_request_data(hub, request):
# type: (Hub, Request) -> Union[Optional[str], AnnotatedValue]
def get_aiohttp_request_data(request):
# type: (Request) -> Union[Optional[str], AnnotatedValue]
bytes_body = request._read_bytes

if bytes_body is not None:
# we have body to show
if not request_body_within_bounds(hub.client, len(bytes_body)):
if not request_body_within_bounds(sentry_sdk.get_client(), len(bytes_body)):
return AnnotatedValue.removed_because_over_size_limit()

encoding = request.charset or "utf-8"
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/argv.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys

from sentry_sdk.hub import Hub
import sentry_sdk
from sentry_sdk.integrations import Integration
from sentry_sdk.scope import add_global_event_processor

Expand All @@ -21,7 +21,7 @@ def setup_once():
@add_global_event_processor
def processor(event, hint):
# type: (Event, Optional[Hint]) -> Optional[Event]
if Hub.current.get_integration(ArgvIntegration) is not None:
if sentry_sdk.get_client().get_integration(ArgvIntegration) is not None:
extra = event.setdefault("extra", {})
# If some event processor decided to set extra to e.g. an
# `int`, don't crash. Not here.
Expand Down
13 changes: 5 additions & 8 deletions sentry_sdk/integrations/atexit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import sys
import atexit

from sentry_sdk.hub import Hub
import sentry_sdk
from sentry_sdk import Scope
from sentry_sdk.utils import logger
from sentry_sdk.integrations import Integration

Expand Down Expand Up @@ -46,14 +47,10 @@ def setup_once():
def _shutdown():
# type: () -> None
logger.debug("atexit: got shutdown signal")
hub = Hub.main
integration = hub.get_integration(AtexitIntegration)
client = sentry_sdk.get_client()
integration = client.get_integration(AtexitIntegration)
if integration is not None:
logger.debug("atexit: shutting down client")

# If there is a session on the hub, close it now.
hub.end_session()

# If an integration is there, a client has to be there.
client = hub.client # type: Any
Scope.get_isolation_scope().end_session()
client.close(callback=integration.callback)
5 changes: 2 additions & 3 deletions sentry_sdk/integrations/dedupe.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sentry_sdk.hub import Hub
import sentry_sdk
from sentry_sdk.utils import ContextVar
from sentry_sdk.integrations import Integration
from sentry_sdk.scope import add_global_event_processor
Expand Down Expand Up @@ -27,8 +27,7 @@ def processor(event, hint):
if hint is None:
return event

integration = Hub.current.get_integration(DedupeIntegration)

integration = sentry_sdk.get_client().get_integration(DedupeIntegration)
if integration is None:
return event

Expand Down
12 changes: 4 additions & 8 deletions sentry_sdk/integrations/excepthook.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys

from sentry_sdk.hub import Hub
import sentry_sdk
from sentry_sdk.utils import capture_internal_exceptions, event_from_exception
from sentry_sdk.integrations import Integration

Expand Down Expand Up @@ -45,20 +45,16 @@ def _make_excepthook(old_excepthook):
# type: (Excepthook) -> Excepthook
def sentry_sdk_excepthook(type_, value, traceback):
# type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None
hub = Hub.current
integration = hub.get_integration(ExcepthookIntegration)
integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration)

if integration is not None and _should_send(integration.always_run):
# If an integration is there, a client has to be there.
client = hub.client # type: Any

with capture_internal_exceptions():
event, hint = event_from_exception(
(type_, value, traceback),
client_options=client.options,
client_options=sentry_sdk.get_client().options,
mechanism={"type": "excepthook", "handled": False},
)
hub.capture_event(event, hint=hint)
sentry_sdk.capture_event(event, hint=hint)

return old_excepthook(type_, value, traceback)

Expand Down
33 changes: 18 additions & 15 deletions sentry_sdk/integrations/httpx.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from sentry_sdk import Hub
import sentry_sdk
from sentry_sdk.consts import OP, SPANDATA
from sentry_sdk.integrations import Integration, DidNotEnable
from sentry_sdk.scope import Scope
from sentry_sdk.tracing import BAGGAGE_HEADER_NAME
from sentry_sdk.tracing_utils import should_propagate_trace
from sentry_sdk.utils import (
SENSITIVE_DATA_SUBSTITUTE,
capture_internal_exceptions,
ensure_integration_enabled,
ensure_integration_enabled_async,
logger,
parse_url,
)
Expand Down Expand Up @@ -42,17 +45,14 @@ def _install_httpx_client():
# type: () -> None
real_send = Client.send

@ensure_integration_enabled(HttpxIntegration, real_send)
def send(self, request, **kwargs):
# type: (Client, Request, **Any) -> Response
hub = Hub.current
if hub.get_integration(HttpxIntegration) is None:
return real_send(self, request, **kwargs)

parsed_url = None
with capture_internal_exceptions():
parsed_url = parse_url(str(request.url), sanitize=False)

with hub.start_span(
with sentry_sdk.start_span(
op=OP.HTTP_CLIENT,
description="%s %s"
% (
Expand All @@ -66,8 +66,11 @@ def send(self, request, **kwargs):
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)

if should_propagate_trace(hub, str(request.url)):
for key, value in hub.iter_trace_propagation_headers():
if should_propagate_trace(sentry_sdk.get_client(), str(request.url)):
for (
key,
value,
) in Scope.get_current_scope().iter_trace_propagation_headers():
logger.debug(
"[Tracing] Adding `{key}` header {value} to outgoing request to {url}.".format(
key=key, value=value, url=request.url
Expand Down Expand Up @@ -95,17 +98,14 @@ def _install_httpx_async_client():
# type: () -> None
real_send = AsyncClient.send

@ensure_integration_enabled_async(HttpxIntegration, real_send)
async def send(self, request, **kwargs):
# type: (AsyncClient, Request, **Any) -> Response
hub = Hub.current
if hub.get_integration(HttpxIntegration) is None:
return await real_send(self, request, **kwargs)

parsed_url = None
with capture_internal_exceptions():
parsed_url = parse_url(str(request.url), sanitize=False)

with hub.start_span(
with sentry_sdk.start_span(
op=OP.HTTP_CLIENT,
description="%s %s"
% (
Expand All @@ -119,8 +119,11 @@ async def send(self, request, **kwargs):
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)

if should_propagate_trace(hub, str(request.url)):
for key, value in hub.iter_trace_propagation_headers():
if should_propagate_trace(sentry_sdk.get_client(), str(request.url)):
for (
key,
value,
) in Scope.get_current_scope().iter_trace_propagation_headers():
logger.debug(
"[Tracing] Adding `{key}` header {value} to outgoing request to {url}.".format(
key=key, value=value, url=request.url
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/modules.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sentry_sdk.hub import Hub
import sentry_sdk
from sentry_sdk.integrations import Integration
from sentry_sdk.scope import add_global_event_processor
from sentry_sdk.utils import _get_installed_modules
Expand All @@ -22,7 +22,7 @@ def processor(event, hint):
if event.get("type") == "transaction":
return event

if Hub.current.get_integration(ModulesIntegration) is None:
if sentry_sdk.get_client().get_integration(ModulesIntegration) is None:
return event

event["modules"] = _get_installed_modules()
Expand Down
Loading
Loading