Skip to content

Commit

Permalink
Migrate from raven to sentry-sdk (#2620)
Browse files Browse the repository at this point in the history
  • Loading branch information
maudetes authored Jun 14, 2021
1 parent 6a6197c commit 9bc0f73
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Current (in progress)

- Migrate from raven to sentry-sdk [#2620](https://github.com/opendatateam/udata/pull/2620)
- Add a UdataCleaner class to use udata's markdown configuration on SafeMarkup as well [#2619](https://github.com/opendatateam/udata/pull/2619)
- Fix schema name display in resource modal [#2617](https://github.com/opendatateam/udata/pull/2617)

Expand Down
2 changes: 1 addition & 1 deletion requirements/sentry.pip
Original file line number Diff line number Diff line change
@@ -1 +1 @@
raven[flask] >= 5.8.0
sentry-sdk[flask] >= 1.1.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def pip(filename):
tests_require=tests_require,
extras_require={
'test': tests_require,
'sentry': ['raven[flask]>=6.1.0'],
'sentry': ['sentry-sdk[flask] >= 1.1.0'],
},
entry_points={
'console_scripts': [
Expand Down
68 changes: 38 additions & 30 deletions udata/sentry.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import pkg_resources
import re
import warnings

from werkzeug.exceptions import HTTPException
from udata import entrypoints
Expand All @@ -11,18 +12,28 @@
log = logging.getLogger(__name__)

RE_DSN = re.compile(
r'(?P<scheme>https?)://(?P<client_id>[0-9a-f]+):[0-9a-f]+'
'@(?P<domain>.+)/(?P<site_id>\d+)')
r'(?P<scheme>https?)://(?P<client_id>[0-9a-f]+)(?::(?P<secret>[0-9a-f]+))?'
r'@(?P<domain>.+)/(?P<site_id>\d+)')

SECRET_DSN_DEPRECATED_MSG = 'DSN with secret is deprecated, use a public DSN instead'
ERROR_PARSE_DSN_MSG = 'Unable to parse Sentry DSN'

# Controlled exceptions that Sentry should ignore
IGNORED_EXCEPTIONS = HTTPException, PermissionDenied, UploadProgress


def public_dsn(dsn):
'''Transform a standard Sentry DSN into a public one'''
'''Check if DSN is public or raise a warning and turn it into a public one'''
m = RE_DSN.match(dsn)
if not m:
log.error('Unable to parse Sentry DSN')
log.error(ERROR_PARSE_DSN_MSG)
raise ValueError(ERROR_PARSE_DSN_MSG)

if not m["secret"]:
return dsn

log.warning(SECRET_DSN_DEPRECATED_MSG)
warnings.warn(SECRET_DSN_DEPRECATED_MSG, category=DeprecationWarning)

public = '{scheme}://{client_id}@{domain}/{site_id}'.format(
**m.groupdict())
return public
Expand All @@ -31,42 +42,39 @@ def public_dsn(dsn):
def init_app(app):
if app.config['SENTRY_DSN']:
try:
from raven.contrib.celery import (
register_signal, register_logger_signal
)
from raven.contrib.flask import Sentry
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.celery import CeleryIntegration
except ImportError:
log.error('raven is required to use Sentry')
log.error('sentry-sdk is required to use Sentry')
return

sentry = Sentry()
tags = app.config['SENTRY_TAGS']
log_level_name = app.config['SENTRY_LOGGING']
if log_level_name:
log_level = getattr(logging, log_level_name.upper())
if log_level:
sentry.logging = True
sentry.level = log_level
sentry_public_dsn = public_dsn(app.config['SENTRY_DSN'])

# Do not send HTTPExceptions
exceptions = set(app.config['SENTRY_IGNORE_EXCEPTIONS'])
for exception in IGNORED_EXCEPTIONS:
exceptions.add(exception)
app.config['SENTRY_IGNORE_EXCEPTIONS'] = list(exceptions)

app.config['SENTRY_PUBLIC_DSN'] = public_dsn(app.config['SENTRY_DSN'])
sentry_sdk.init(
dsn=sentry_public_dsn,
integrations=[FlaskIntegration(), CeleryIntegration()],
ignore_errors=list(exceptions)
)

# Set log level
log_level_name = app.config['SENTRY_LOGGING']
if log_level_name:
log_level = getattr(logging, log_level_name.upper())
sentry_sdk.set_level(log_level)

# Set sentry tags
tags = app.config['SENTRY_TAGS']
for tag_key in tags:
sentry_sdk.set_tag(tag_key, tags[tag_key])
# Versions Management: uData and plugins versions as tags.
for dist in entrypoints.get_plugins_dists(app):
if dist.version:
tags[dist.project_name] = dist.version
sentry_sdk.set_tag(dist.project_name, dist.version)
# Do not forget udata itself
tags['udata'] = pkg_resources.get_distribution('udata').version

sentry.init_app(app)

# register a custom filter to filter out duplicate logs
register_logger_signal(sentry.client, loglevel=sentry.level)

# hook into the Celery error handler
register_signal(sentry.client)
sentry_sdk.set_tag('udata', pkg_resources.get_distribution('udata').version)

0 comments on commit 9bc0f73

Please sign in to comment.