Measure your Celery tasks¶
A request that returns in 40 ms because it queued the work has moved the time somewhere else. Install Celery and django-statsd starts reporting on where it went. There’s no setting to turn on.
# One task, run and then failed
celery.status.task_failure
celery.status.task_postrun
celery.status.task_prerun
myproject.celery.myproject.tasks.send_invoice.hit
myproject.celery.myproject.tasks.send_invoice.total
myproject.celery.site.hit
Two families, and they’re prefixed differently, which surprises people.
myproject.celery.<task name> follows your STATSD_PREFIX and
holds the timings: total for the task and hit for the counter,
named after the task so myproject.tasks.send_invoice reports under
its own dotted path. myproject.celery.site.hit counts every task
the way view.site.hit counts every request.
celery.status.* carries no prefix at all. Those counters are wired
to every signal Celery exports, one counter per signal, so
task_failure above is a task that failed. If you run more than one
project against one statsd, these names collide, and there’s no setting
to change it. I give each project its own statsd for exactly this
reason, and I found out by wondering why task_failure was running
at twice the rate my logs said.
Timers survive a failure¶
task_prerun opens the timing and task_postrun closes it.
task_failure clears the scope instead, which stops a failed task
from leaving a timer open for whatever the worker picks up next.
The module-level helpers from Measure your own code work inside a task, because the scope Celery’s signals open is the one they write to.
A note on 3.0¶
Before 3.0 these receivers were connected with Celery’s default weak references. They were closures, so they were collected immediately and never fired. If you ran django-statsd and saw no Celery counters, that was why, and it’s fixed.