Question

I'm trying to setup raven to log to sentry asynchronously using celery. I think I've set things up correctly, but but the send_raw functions in the CeleryClient are not being called (and nothing is being picked up in sentry or celery). Things work if I don't change the SENTRY_CLIENT setting below (the logs appear in sentry). My setting are:

SENTRY_CLIENT = 'raven.contrib.django.celery.CeleryClient'

Installed apps:

'raven.contrib.django',    
# sentry.client.celery should be replaced with raven.contrib.django.celery in INSTALLED_APPS.    
'raven.contrib.django.celery',    

Logging:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'root': {
        'level': 'WARNING', # anything warning or above will go to sentry...
        'handlers': ['sentry'], # TARAS this is what sends all errors to Sentry
    },
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
    },
    'handlers': {
        'sentry': {
            'level': 'ERROR',
            'class': 'raven.contrib.django.handlers.SentryHandler', # this is what communicates to Sentry
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        'django.db.backends': {
            'level': 'ERROR',
            'handlers': ['console'],
            'propagate': False,
        },
        'raven': {
            'level': 'DEBUG',
            # class logging.StreamHandler(stream=None)
            # Returns a new instance of the StreamHandler class. If stream is specified, the instance will use it for logging output; otherwise, sys.stderr will be used.            
            'handlers': ['sentry'], # sentry hits sentry configuration above, console by default according to the above definition of streamhandler hits stderr
            'propagate': False,
        },
        'sentry.errors': {
            'level': 'DEBUG',
            'handlers': ['console'],
            'propagate': False,
        },
    },
}

I have modified CeleryClient to

class CeleryClient(CeleryMixin, DjangoClient):
    def send_integrated(self, kwargs):
        self.send_raw_integrated.delay(kwargs)
        print "yo"

    @task(routing_key='sentry')
    def send_raw_integrated(self, kwargs):
        super(CeleryClient, self).send_integrated(kwargs)
        print "yo2"

And the traces don't come out

Was it helpful?

Solution

The celery client in raven uses a routing key on the task:

class CeleryMixin(object):
    def send_encoded(self, *args, **kwargs):
        "Errors through celery"
        self.send_raw.delay(*args, **kwargs)

    @task(routing_key='sentry')
    def send_raw(self, *args, **kwargs):
        return super(CeleryMixin, self).send_encoded(*args, **kwargs)

Django by default uses a direct exchange type:

http://docs.celeryproject.org/en/latest/userguide/routing.html

Which means (I believe) that the messages produced by celery will not be routed to a queue (and thus will never be picked up).

You can define this, for example:

CELERY_QUEUES = {
    "default": {
        "exchange": "default",
        "binding_key": "default"},
    "sentry": {
        "exchange": "default",
        "binding_key": "sentry"},
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top