7

There are many integrations for raven, including python logging. On the one side, twisted does not use python's logging. And on the other side, there is no direct integration for raven in twisted.

So what is the current best practice for using raven in a twisted based setup?

Elrond
  • 901
  • 9
  • 23
  • 1
    Adding as a comment rather than an answer because I've never used Sentry / Raven directly, so I don't know that this helps. However, Twisted has support for Python standard library logging. Have you seen the docs for https://twistedmatrix.com/documents/13.1.0/api/twisted.python.log.PythonLoggingObserver.html ? – Glyph Sep 28 '13 at 00:25
  • 1
    @Glyph: This might be part of the answer. Routing logs first to python and then from there to raven. To me this feels like a workaround, which is why I am asking for best current practice. – Elrond Sep 28 '13 at 09:31
  • The phrase "best practice" implies that everyone is doing a thing, and that there's a generally recognized, correct way to do it which is part of some (possibly official) body of knowledge. Since it seems few people are using Sentry and Raven with Twisted, there may well be ways to get it to work, but none of them is going to be a "best practice". – Glyph Mar 18 '14 at 02:14

3 Answers3

11

raven's captureException can only be called without arguments if there is an exception active, which is not always the case when a log observer is called. So, instead, pull the exception information out of the Failure that gets logged:

from twisted.python import log
from raven import Client


client = Client(dsn='twisted+http://YOUR_DSN_HERE')

def logToSentry(event):
    if not event.get('isError') or 'failure' not in event:
        return

    f = event['failure']
    client.captureException((f.type, f.value, f.getTracebackObject()))

log.addObserver(logToSentry)
habnabit
  • 9,906
  • 3
  • 32
  • 26
  • 1. Where does the `t` in `t.value` come from? 2. What about doing `client.captureMessage(event)` before the `return` in the no error case? – Elrond Aug 01 '14 at 13:49
  • @Elrond, oops, that should've been `f.value`. And sure, you could `captureMessage` if you wanted to. – habnabit Aug 01 '14 at 17:42
3

user1252307 answer is a great start, but on the sentry side you get a relatively unhelpful dictionary and no stack trace.

If you are trying to view and track down unexpected exceptions try this small change to the log_sentry function:

from twisted.python import log
from raven import Client

client = Client(dsn='twisted+http://YOUR_DSN_HERE')

def log_sentry(dictionary):
    if dictionary.get('isError'):
        if 'failure' in dictionary:
            client.captureException() # Send the current exception info to Sentry.
        else:
            #format the dictionary in whatever way you want
            client.captureMessage(dictionary)

log.addObserver(log_sentry)

There maybe a better way to filter non exception based error message, and this might try to emit exception information that doesn't exist where there are failures which aren't exceptions.

amjoconn
  • 2,113
  • 2
  • 17
  • 17
  • This is insufficient in most cases because there is often no current exception when the log observer gets called. – habnabit Jun 19 '14 at 18:22
1
from twisted.python import log
from raven import Client

client = Client(dsn='twisted+http://YOUR_DSN_HERE')

def log_sentry(dictionary):
    if dictionary.get('isError'):
        #format the dictionary in whatever way you want
        client.captureMessage(dictionary)

log.addObserver(log_sentry)
kev
  • 8,928
  • 14
  • 61
  • 103