I'd like a celery task to be able to get the name of the worker executing it, for logging purposes. I need to handle this from within the task, rather than querying the broker directly. Is there a way to do this? I'm using celery with RabbitMQ, if that matters.
-
Please set my solution to resolved if it worked for you :) – Roy Iacob May 26 '14 at 05:55
4 Answers
Use the celeryd_after_setup
signal to capture the worker name like this:
from celery.signals import celeryd_after_setup
@celeryd_after_setup.connect
def capture_worker_name(sender, instance, **kwargs):
os.environ["WORKER_NAME"] = '{0}'.format(sender)

- 294
- 2
- 5
-
1This should be the accepted answer, however I would put the name inside the celery config, and not in an environment variable – Mart10 Dec 20 '18 at 15:19
-
1If you're using the `celery_worker` fixture to test, use the `worker_init` signal instead as `celeryd_after_setup` is not called in test. – Sirupsen Jan 20 '22 at 22:49
You need to utilize billiard which holds the workers:
from celery import task
from billiard import current_process
@task
def getName():
p = current_process()
return p.index
Then make a global dictionary that maps ids->names on process creation.

- 412
- 3
- 13
-
3This isn't quite what I was looking for. When you start a celery worker, you can give it a name (-n flag). I'm wondering if there is a way to get that name from within the task. – imichaeldotorg May 26 '14 at 17:46
-
1not quite as straight forward but why not make a global dict of ids->names? – Roy Iacob May 27 '14 at 00:43
-
billiard is definitely the key, but this solution does not get the name, as requested. I added a small update in my answer. – cacois Aug 19 '14 at 12:57
I also needed the worker name for reporting purposes so I tried @cacois solution but it doesn't seem to work with eventlet (current_process() doesn't have an initargs attribute). So I'll leave my solution here for future references:
from celery import task
@task(bind=True)
def getName(self):
return self.request.hostname
The name of the attribute sounds weird to me, but that contains the name specified with the "-n" option when launching the worker. self works like you would expect from a class method, you don't need to specify it when calling the function (eg: getName.delay()).

- 95
- 1
- 1
-
You don't need to do this every time you run a task. Way easier to capture the worker name on connect. See my answer bellow. – Teo Sibileau Jul 25 '17 at 16:57
-
You were originally looking for the name you put in with the -n flag, right? It's in the initargs array. Here's a modified version of the answer that gets you that:
from celery import task
from billiard import current_process
@task
def getName():
p = current_process()
return p.initargs[1].split('@')[1]

- 2,036
- 2
- 19
- 19
-
Unfortunately this seems to no longer work with recent celery versions. `current_process()` now returns a `ForkProcess` object, which has no `initargs`. – ForeverWintr Oct 04 '18 at 19:29