The only way I found this is to overwrite some of the internal methods of Raven.
The main idea is that we want to change the handle_exception() method in the Sentry Raven class. There I can add the interface sentry.interfaces.User , which was already mentioned in the question. To do this, I need my own factory filter, which I can use instead of the default Paste filter that comes with Raven and that uses my own Sentry subclass.
In my project, I have a sentry.py file:
from raven.middleware import Sentry from raven.utils.wsgi import get_current_url, get_headers, get_environ from raven.base import Client def sentry_filter_factory(app, global_conf, **kwargs): """ Overwritten just to override the 'Sentry' class being used. """ client = Client(**kwargs) return UserEnhancedSentry(app, client) class UserEnhancedSentry(Sentry): """ Overriding raven.middleware.Sentry handle_exception() method to inject the sentry.interfaces.User interface. This relies on the data previously being injected into the environ by 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'),
In my setup.py I declare a factory filter as an entry point:
entry_points = """\ [paste.app_factory] main = myapp:main [paste.filter_app_factory] raven = myapp.sentry:sentry_filter_factory """,
Now I can use the entry point to declare a filter in the .ini configuration file and integrate it into the Paste pipeline, as described in Insert documents :
[pipeline:main] pipeline = sentry myapp [filter:sentry] use = egg:myapp#raven dsn = https://abc: def@app.getsentry.com /123
So, whenever a Sentry filter receives an exception, it will not only store data about the HTTP request, but also about the user if he finds information about this in the environ . All I need to do now is to enter user information from the session, which I do with user animation:
def sentry_user_tween_factory(handler, registry): """ Returns a tween that does nothing but enhance the environ by information about the currently logged in user, which will be useful for the Sentry report in case there an 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)
It all seems unreasonably complicated, but I'm glad I found a way to make it work, finally.