This commit is contained in:
Raphael Michel
2022-10-26 11:58:44 +02:00
parent 7c5fac306a
commit 7d3cd16785
3 changed files with 53 additions and 11 deletions

View File

@@ -64,6 +64,10 @@ class EventPluginSignal(django.dispatch.Signal):
# Send to all events! # Send to all events!
return True return True
# If sentry packed this in a wrapper, unpack that
if "sentry" in receiver.__module__:
receiver = receiver.__wrapped__
# Find the Django application this belongs to # Find the Django application this belongs to
searchpath = receiver.__module__ searchpath = receiver.__module__
core_module = any([searchpath.startswith(cm) for cm in settings.CORE_MODULES]) core_module = any([searchpath.startswith(cm) for cm in settings.CORE_MODULES])

View File

@@ -22,12 +22,14 @@
import re import re
import weakref import weakref
from collections import OrderedDict from collections import OrderedDict
from functools import wraps
from celery.exceptions import Retry from celery.exceptions import Retry
from django.dispatch import Signal
from sentry_sdk import Hub from sentry_sdk import Hub
from sentry_sdk.integrations.django import ( from sentry_sdk.consts import OP
LEGACY_RESOLVER, DjangoIntegration, _before_get_response, _set_user_info, from sentry_sdk.integrations import django as djangosentry
) from sentry_sdk.integrations.django.signals_handlers import _get_receiver_name
from sentry_sdk.utils import capture_internal_exceptions from sentry_sdk.utils import capture_internal_exceptions
MASK = '*' * 8 MASK = '*' * 8
@@ -45,6 +47,37 @@ KEYS = frozenset([
VALUES_RE = re.compile(r'^(?:\d[ -]*?){13,16}$') VALUES_RE = re.compile(r'^(?:\d[ -]*?){13,16}$')
def patched_patch_signals():
# This is a workaround for https://github.com/getsentry/sentry-python/issues/1700
# that needs to stay until it is fixed
old_live_receivers = Signal._live_receivers
def _sentry_live_receivers(self, sender):
hub = Hub.current
receivers = old_live_receivers(self, sender)
def sentry_receiver_wrapper(receiver):
@wraps(receiver)
def wrapper(*args, **kwargs):
signal_name = _get_receiver_name(receiver)
with hub.start_span(
op=OP.EVENT_DJANGO,
description=signal_name,
) as span:
span.set_data("signal", signal_name)
return receiver(*args, **kwargs)
return wrapper
for idx, receiver in enumerate(receivers):
receivers[idx] = sentry_receiver_wrapper(receiver)
return receivers
Signal._live_receivers = _sentry_live_receivers
def scrub_data(data): def scrub_data(data):
if isinstance(data, dict): if isinstance(data, dict):
for k, v in data.items(): for k, v in data.items():
@@ -83,13 +116,13 @@ def _make_event_processor(weak_request, integration):
return event return event
with capture_internal_exceptions(): with capture_internal_exceptions():
_set_user_info(request, event) djangosentry._set_user_info(request, event)
request_info = event.setdefault("request", {}) request_info = event.setdefault("request", {})
request_info["cookies"] = dict(request.COOKIES) request_info["cookies"] = dict(request.COOKIES)
# Sentry's DjangoIntegration already sets the transcation, but it gets confused by our multi-domain stuff # Sentry's DjangoIntegration already sets the transaction, but it gets confused by our multi-domain stuff
# where the URL resolver changes in the middleware stack. Additionally, we'd like to get the method. # where the URL resolver changes in the middleware stack. Additionally, we'd like to get the method.
url = LEGACY_RESOLVER.resolve(request.path_info, getattr(request, "urlconf", None)) url = djangosentry.LEGACY_RESOLVER.resolve(request.path_info, getattr(request, "urlconf", None))
if hasattr(request, 'event_domain'): if hasattr(request, 'event_domain'):
url = '/{organizer}/{event}' + url url = '/{organizer}/{event}' + url
elif hasattr(request, 'organizer_domain'): elif hasattr(request, 'organizer_domain'):
@@ -112,11 +145,16 @@ def _make_event_processor(weak_request, integration):
return event_processor return event_processor
class PretixSentryIntegration(DjangoIntegration): class PretixSentryIntegration(djangosentry.DjangoIntegration):
@staticmethod @staticmethod
def setup_once(): def setup_once():
DjangoIntegration.setup_once() # This is a workaround for https://github.com/getsentry/sentry-python/issues/1700
# that needs to stay until it is fixed
djangosentry.patch_signals = patched_patch_signals
djangosentry.signals_handlers.patch_signals = patched_patch_signals
djangosentry.DjangoIntegration.setup_once()
from django.core.handlers.base import BaseHandler from django.core.handlers.base import BaseHandler
# DjangoIntegration already patched get_response, we patch it again to add our custom # DjangoIntegration already patched get_response, we patch it again to add our custom
@@ -126,7 +164,7 @@ class PretixSentryIntegration(DjangoIntegration):
def sentry_patched_get_response(self, request): def sentry_patched_get_response(self, request):
hub = Hub.current hub = Hub.current
integration = hub.get_integration(DjangoIntegration) integration = hub.get_integration(djangosentry.DjangoIntegration)
if integration is not None: if integration is not None:
with hub.configure_scope() as scope: with hub.configure_scope() as scope:
scope.add_event_processor( scope.add_event_processor(
@@ -142,7 +180,7 @@ class PretixSentryIntegration(DjangoIntegration):
patch_get_response_async, patch_get_response_async,
) )
patch_get_response_async(BaseHandler, _before_get_response) patch_get_response_async(BaseHandler, djangosentry._before_get_response)
def ignore_retry(event, hint): def ignore_retry(event, hint):

View File

@@ -221,7 +221,7 @@ setup(
'redis==4.3.*', 'redis==4.3.*',
'reportlab==3.6.*', 'reportlab==3.6.*',
'requests==2.28.*', 'requests==2.28.*',
'sentry-sdk==1.10.*', 'sentry-sdk==1.10.*', # when upgrading, check https://github.com/getsentry/sentry-python/issues/1700
'sepaxml==2.5.*', 'sepaxml==2.5.*',
'slimit', 'slimit',
'static3==0.7.*', 'static3==0.7.*',