diff --git a/django_statsd/celery.py b/django_statsd/celery.py new file mode 100644 index 0000000..b6654af --- /dev/null +++ b/django_statsd/celery.py @@ -0,0 +1,59 @@ +from __future__ import absolute_import + +from django_statsd.clients import statsd +import time + +_task_start_times = {} + + +def on_task_sent(sender=None, task_id=None, task=None, **kwds): + """ + Handle Celery ``task_sent`` signals. + """ + # Increase statsd counter. + statsd.incr('celery.%s.sent' % task) + + +def on_task_prerun(sender=None, task_id=None, task=None, **kwds): + """ + Handle Celery ``task_prerun``signals. + """ + # Increase statsd counter. + statsd.incr('celery.%s.start' % task.name) + + # Keep track of start times. (For logging the duration in the postrun.) + _task_start_times[task_id] = time.time() + + +def on_task_postrun(sender=None, task_id=None, task=None, **kwds): + """ + Handle Celery ``task_postrun`` signals. + """ + # Increase statsd counter. + statsd.incr('celery.%s.done' % task.name) + + # Log duration. + start_time = _task_start_times.pop(task_id, False) + if start_time: + ms = int((time.time() - start_time) * 1000) + statsd.timing('celery.%s.runtime' % task.name, ms) + + +def on_task_failure(sender=None, task_id=None, task=None, **kwds): + """ + Handle Celery ``task_failure`` signals. + """ + # Increase statsd counter. + statsd.incr('celery.%s.failure' % task) + + +def register_celery_events(): + try: + from celery import signals + except ImportError: + pass + else: + signals.task_sent.connect(on_task_sent) + signals.task_prerun.connect(on_task_prerun) + signals.task_postrun.connect(on_task_postrun) + signals.task_failure.connect(on_task_failure) diff --git a/django_statsd/models.py b/django_statsd/models.py new file mode 100644 index 0000000..3aedbb3 --- /dev/null +++ b/django_statsd/models.py @@ -0,0 +1,5 @@ +from .celery import register_celery_events +from django.conf import settings + +if getattr(settings, 'STATSD_CELERY_SIGNALS', False): + register_celery_events() diff --git a/docs/index.rst b/docs/index.rst index 2a2733c..d75afde 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -209,6 +209,17 @@ would look that up on the graphite server with the key:: stats.addons.view.GET +Celery signals integration +-------------------------- + +You can log all the ``task_sent``, ``task_prerun``, ``task_postrun`` and +``task_failure`` signals of celery along with the duration of succesful tasks. + +To enable this, add the following to your Django settings:: + + STATSD_CELERY_SIGNALS = True + + Front end timing integration ----------------------------