All Unkept
Posted in: Python, Web development, Django  —  February 07, 2012 at 09:04 PM

Async Raven/Sentry client with Django/Python

by Luke Plant

Sentry really ought to use UDP, not TCP, because you don't want logging functionality to stall or even slow down your main application. At the moment, it doesn't support that, although there have been some promising commits.

For my usage (a web application), this means that you can really only use Sentry for logging exceptions, and not for anything less important.

However, there are some alternatives to UDP that make Sentry usable for more than exceptions. You could use a queue process like Celery or RabbitMQ (apparently what they use at Disqus).

A more light weight alternative, however, is an asynchronous client that does its work in the background, and so doesn't block your web server thread.

There is some hopeful looking code in raven.contrib.async, but unfortunately it currently has a critical bug (Raven 1.4.2).

However, using that code I cobbled together my own, and this one subclasses DjangoClient, which is what I need:

from raven.contrib.django import DjangoClient
from raven.contrib.async import AsyncWorker


class AsyncDjangoClient(DjangoClient):
    """
    This client uses a single background thread to dispatch errors.
    """
    def __init__(self, *args, **kwargs):
        self.worker = AsyncWorker()
        super(AsyncDjangoClient, self).__init__(*args, **kwargs)

    def send_sync(self, **kwargs):
        super(AsyncDjangoClient, self).send(**kwargs)

    def send(self, **kwargs):
        self.worker.queue.put_nowait((self.send_sync, kwargs))

Then you need to set SENTRY_CLIENT in your settings to point to this class.

(If you're not using Django, you should be able to do something similar.)

This is working fine for me - I can now enable the Sentry 404 middleware and not see any slowdown on my app, as opposed to the synchronous client which was slowing down 404 responses massively because my Sentry server is not on the same box as my main web app.

I should say this is use at own risk - the AsyncClient in Raven is undocumented as well as broken, so I don't know if it is considered a sensible approach or not!

Comments §

blog comments powered by Disqus