Request logging in Opbeat

Opbeat is undeniably awesome.
It logs all the things, it provides useful traces, and it often let's you know things are broken before your users even start suspecting anything.

When using it with Django it's generally very helpful, logging all unhandled exceptions and allowing you to add nice extra context to your logs, like request information (URL and header data for the request etc).

There are some situations however where the request object might not be available, for example when manually logging something quite deep in the stack (away from the view).

In those cases the request information might still be very important for debugging when things go wrong!

Googling for solutions didn't help much, but looking in opbeat's python code I stumbled upon OpbeatLogMiddleware. I was unable to find it documented anywhere. The installation instructions recommend enabling only OpbeatAPMMiddleware.

After having a play with enabling it and trying things out, it turns out it does exactly what we need.

How to?

To enable request logging away from the view/for manual logging further down the stack you just need to change your setup to:

MIDDLEWARE_CLASSES = (
    'opbeat.contrib.django.middleware.OpbeatAPMMiddleware',
    'opbeat.contrib.django.middleware.OpbeatLogMiddleware',
    # ...
)

and you're good to go!

The way this works is, the middleware will store the current request to the local thread. The log handler will then try to grab it from there when possible and append it to the captured data.