python - How do I report the currently logged in user to Sentry? -
i'm using sentry (raven 3.4.1) on user-facing python/pyramid webapp. sentry seems have ability track , how many users experienced exception. (see example sentry 6.2.0 changelog, mentions: "streams have recorded user data show number of unique users event has happened to.") how supply information raven, shows in sentry?
can if pass exception raven manually? right now, i'm using sentryhandler
logging handler, attached root logger, , egg:raven#raven
filter in pastedeploy pipeline. (following official raven configuration docs pyramid closely.)
is there trick pass information raven? can maybe set local variable name somewhere @ bottom of stack, have loaded user's session, , raven pick automatically? what's best practice here?
i suspect this has i'm trying do, can't find in raven docs.
the way found overwrite internal methods of raven.
the basic idea want modify handle_exception()
method on sentry
class of raven. there, can inject sentry.interfaces.user
interface mentioned in question. this, need own filter factory, can use instead of default paste filter comes raven , uses own subclass of sentry
.
in project, have file sentry.py
:
from raven.middleware import sentry raven.utils.wsgi import get_current_url, get_headers, get_environ raven.base import client def sentry_filter_factory(app, global_conf, **kwargs): """ overwritten override 'sentry' class being used. """ client = client(**kwargs) return userenhancedsentry(app, client) class userenhancedsentry(sentry): """ overriding raven.middleware.sentry's handle_exception() method inject sentry.interfaces.user interface. relies on data being injected environ our custom tween. """ def handle_exception(self, environ): data={} data['sentry.interfaces.http'] = { 'method': environ.get('request_method'), 'url': get_current_url(environ, strip_querystring=true), 'query_string': environ.get('query_string'), # todo # 'data': environ.get('wsgi.input'), 'headers': dict(get_headers(environ)), 'env': dict(get_environ(environ)), } if environ.has_key('myapp.user'): user_id, username, email = environ.get('myapp.user') ip_address = environ.get('http_x_forwarded_for', environ.get('remote_addr')) data['sentry.interfaces.user'] = { 'id': user_id, 'username': username, 'email': email, 'ip_address': ip_address, } event_id = self.client.captureexception(data=data) return event_id
in setup.py
, declare filter factory entry point:
entry_points = """\ [paste.app_factory] main = myapp:main [paste.filter_app_factory] raven = myapp.sentry:sentry_filter_factory """,
now can use entry point declare filter in configuration .ini file , integrate paste pipeline, described in paste docs:
[pipeline:main] pipeline = sentry myapp [filter:sentry] use = egg:myapp#raven dsn = https://abc:def@app.getsentry.com/123
so now, whenever sentry filter catches exception, not store data http request, user—assuming can find information in environ
. have inject user information session there, i'm doing custom tween:
def sentry_user_tween_factory(handler, registry): """ returns tween nothing enhance environ information logged in user, useful sentry report in case there's exception """ def sentry_user_tween(request): user = request.session.get('user') if user: request.environ['myapp.user'] = (user.token, user.name, user.email) else: request.environ['myapp.user'] = (0, 'anonymous', none) # proceed next tween/handler response = handler(request) return response return sentry_user_tween config.add_tween('myapp.sentry_user_tween_factory')
that seems unreasonably complicated, i'm happy found way make work, @ last.
Comments
Post a Comment