Switch from raven to sentry_sdk

This commit is contained in:
Raphael Michel
2019-02-05 11:25:39 +01:00
parent b53ee1dc1d
commit bed0a0ceeb
6 changed files with 106 additions and 53 deletions

View File

@@ -8,13 +8,13 @@
<h1>{% trans "Internal Server Error" %}</h1> <h1>{% trans "Internal Server Error" %}</h1>
<p>{% trans "We had trouble processing your request." %}</p> <p>{% trans "We had trouble processing your request." %}</p>
<p>{% trans "If this problem persists, please contact us." %}</p> <p>{% trans "If this problem persists, please contact us." %}</p>
{% if request.sentry.id %} {% if sentry_event_id %}
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
If you contact us, please send us the following code: If you contact us, please send us the following code:
{% endblocktrans %} {% endblocktrans %}
<br> <br>
{{ request.sentry.id }} {{ sentry_event_id }}
</p> </p>
{% endif %} {% endif %}
<p>{{ exception }}</p> <p>{{ exception }}</p>

View File

@@ -7,6 +7,7 @@ from django.template.loader import get_template
from django.utils.functional import Promise from django.utils.functional import Promise
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.decorators.csrf import requires_csrf_token from django.views.decorators.csrf import requires_csrf_token
from sentry_sdk import last_event_id
def csrf_failure(request, reason=""): def csrf_failure(request, reason=""):
@@ -65,5 +66,6 @@ def server_error(request):
except TemplateDoesNotExist: except TemplateDoesNotExist:
return HttpResponseServerError('<h1>Server Error (500)</h1>', content_type='text/html') return HttpResponseServerError('<h1>Server Error (500)</h1>', content_type='text/html')
return HttpResponseServerError(template.render({ return HttpResponseServerError(template.render({
'request': request 'request': request,
'sentry_event_id': last_event_id(),
})) }))

View File

@@ -1,50 +1,96 @@
from threading import Lock import re
import weakref
from collections import OrderedDict
from raven.contrib.celery import SentryCeleryHandler from sentry_sdk import Hub
from raven.contrib.django.apps import RavenConfig from sentry_sdk.integrations.django import DjangoIntegration, _set_user_info
from raven.contrib.django.models import ( from sentry_sdk.utils import capture_internal_exceptions
SentryDjangoHandler, client, get_client, install_middleware,
register_serializers,
)
_setup_lock = Lock() MASK = '*' * 8
KEYS = frozenset([
_initialized = False 'password',
'secret',
'passwd',
'authorization',
'api_key',
'apikey',
'sentry_dsn',
'access_token',
'session',
])
VALUES_RE = re.compile(r'^(?:\d[ -]*?){13,16}$')
class CustomSentryDjangoHandler(SentryDjangoHandler): def scrub_data(data):
def install_celery(self): if isinstance(data, dict):
self.celery_handler = SentryCeleryHandler(client, ignore_expected=True).install() for k, v in data.items():
if isinstance(k, bytes):
key = k.decode('utf-8', 'replace')
else:
key = k
key = key.lower()
data[k] = scrub_data(v)
for blk in KEYS:
if blk in key:
data[k] = MASK
elif isinstance(data, list):
for i, l in enumerate(list(data)):
data[i] = scrub_data(l)
elif isinstance(data, str):
if '=' in data:
# at this point we've assumed it's a standard HTTP query
# or cookie
if '&' in data:
delimiter = '&'
else:
delimiter = ';'
qd = scrub_data(OrderedDict(e.split('=', 1) if '=' in e else (e, None) for e in data.split(delimiter)))
return delimiter.join((k + '=' + v if v is not None else k) for k, v in qd.items())
if VALUES_RE.match(data):
return MASK
return data
def initialize(): def _make_event_processor(weak_request, integration):
global _initialized def event_processor(event, hint):
request = weak_request()
if request is None:
return event
with _setup_lock: with capture_internal_exceptions():
if _initialized: _set_user_info(request, event)
return request_info = event.setdefault("request", {})
request_info["cookies"] = dict(request.COOKIES)
_initialized = True scrub_data(event.get("request", {}))
if 'exception' in event:
exc = event.get("exception", {})
for val in exc.get('values', []):
stack = val.get('stacktrace', {})
for frame in stack.get('frames', []):
scrub_data(frame['vars'])
return event
try: return event_processor
register_serializers()
install_middleware(
'raven.contrib.django.middleware.SentryMiddleware',
(
'raven.contrib.django.middleware.SentryMiddleware',
'raven.contrib.django.middleware.SentryLogMiddleware'))
install_middleware(
'raven.contrib.django.middleware.DjangoRestFrameworkCompatMiddleware')
handler = CustomSentryDjangoHandler()
handler.install()
# instantiate client so hooks get registered
get_client() # NOQA
except Exception:
_initialized = False
class App(RavenConfig): class PretixSentryIntegration(DjangoIntegration):
def ready(self): @staticmethod
initialize() def setup_once():
DjangoIntegration.setup_once()
from django.core.handlers.base import BaseHandler
old_get_response = BaseHandler.get_response
def sentry_patched_get_response(self, request):
hub = Hub.current
integration = hub.get_integration(DjangoIntegration)
if integration is not None:
with hub.configure_scope() as scope:
scope.add_event_processor(
_make_event_processor(weakref.ref(request), integration)
)
return old_get_response(self, request)
BaseHandler.get_response = sentry_patched_get_response

View File

@@ -1,6 +1,7 @@
import configparser import configparser
import os import os
import sys import sys
from urllib.parse import urlparse from urllib.parse import urlparse
from kombu import Queue from kombu import Queue
@@ -564,15 +565,19 @@ LOGGING = {
} }
if config.has_option('sentry', 'dsn'): if config.has_option('sentry', 'dsn'):
INSTALLED_APPS += [ import sentry_sdk
'pretix.sentry.App', from sentry_sdk.integrations.celery import CeleryIntegration
] from sentry_sdk.integrations.logging import ignore_logger
RAVEN_CONFIG = { from .sentry import PretixSentryIntegration
'dsn': config.get('sentry', 'dsn'),
'transport': 'raven.transport.threaded_requests.ThreadedRequestsHTTPTransport', sentry_sdk.init(
'release': __version__, dsn=config.get('sentry', 'dsn'),
'environment': SITE_URL, integrations=[PretixSentryIntegration(), CeleryIntegration()],
} environment=SITE_URL,
release=__version__,
send_default_pii=False
)
ignore_logger('pretix.base.tasks')
CELERY_TASK_SERIALIZER = 'json' CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json'

View File

@@ -29,7 +29,7 @@ csscompressor
django-markup django-markup
markdown<=2.2 markdown<=2.2
bleach==2.* bleach==2.*
raven sentry-sdk==0.7.*
babel babel
django-i18nfield>=1.4.0 django-i18nfield>=1.4.0
django-hijack>=2.1.10,<2.2.0 django-hijack>=2.1.10,<2.2.0

View File

@@ -117,7 +117,7 @@ setup(
'django-markup', 'django-markup',
'markdown<=2.2', 'markdown<=2.2',
'bleach==2.*', 'bleach==2.*',
'raven', 'sentry-sdk==0.7.*',
'babel', 'babel',
'paypalrestsdk==1.13.*', 'paypalrestsdk==1.13.*',
'pycparser==2.13', 'pycparser==2.13',