Получить имя работника сельдерея из задачи сельдерея?

Я хотел бы, чтобы задача сельдерея могла получить имя выполняющего ее работника для целей ведения журнала. Мне нужно справиться с этим из задачи, а не напрямую запрашивать брокера. Есть ли способ сделать это? Я использую сельдерей с RabbitMQ, если это имеет значение.


person imichaeldotorg    schedule 25.05.2014    source источник
comment
Пожалуйста, установите мое решение как разрешенное, если оно сработало для вас :)   -  person Roy Iacob    schedule 26.05.2014


Ответы (4)


Используйте сигнал celeryd_after_setup для захвата имени рабочего процесса следующим образом:

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)
person Teo Sibileau    schedule 26.04.2017
comment
Это должен быть принятый ответ, однако я бы поместил имя в конфигурацию сельдерея, а не в переменную среды. - person Mart10; 20.12.2018

Вам нужно использовать бильярд, который держит рабочих:

from celery import task
from billiard import current_process

@task
def getName():
    p = current_process()
    return p.index

Затем создайте глобальный словарь, который сопоставляет идентификаторы -> имена при создании процесса.

person Roy Iacob    schedule 25.05.2014
comment
Это не совсем то, что я искал. Когда вы запускаете celery worker, вы можете дать ему имя (флаг -n). Мне интересно, есть ли способ получить это имя из задачи. - person imichaeldotorg; 26.05.2014
comment
не так прямолинейно, но почему бы не сделать глобальный список идентификаторов-›имен? - person Roy Iacob; 27.05.2014
comment
бильярд, безусловно, является ключевым, но это решение не получает название, как просили. Я добавил небольшое обновление в свой ответ. - person cacois; 19.08.2014

Мне также нужно было имя рабочего для целей отчетности, поэтому я попробовал решение @cacois, но, похоже, оно не работает с eventlet (current_process() не имеет атрибута initargs). Поэтому я оставлю свое решение здесь для будущих ссылок:

from celery import task

@task(bind=True)
def getName(self):
    return self.request.hostname

Имя атрибута звучит странно для меня, но оно содержит имя, указанное с опцией «-n» при запуске воркера. self работает так, как вы ожидаете от метода класса, вам не нужно указывать его при вызове функции (например: getName.delay()).

person Adrian Macias    schedule 15.09.2016
comment
Вам не нужно делать это каждый раз, когда вы запускаете задачу. Гораздо проще захватить имя рабочего при подключении. Смотрите мой ответ ниже. - person Teo Sibileau; 25.07.2017
comment
Имя хоста — это имя сервера, а не имя работника. - person Cerin; 19.03.2021

Вы изначально искали имя, которое вы вставили с флагом -n, верно? Он находится в массиве initargs. Вот модифицированная версия ответа, которая дает вам это:

from celery import task
from billiard import current_process

@task
def getName():
    p = current_process()
    return p.initargs[1].split('@')[1]
person cacois    schedule 19.08.2014
comment
К сожалению, это больше не работает с последними версиями сельдерея. current_process() теперь возвращает объект ForkProcess, у которого нет initargs. - person ForeverWintr; 04.10.2018