Отправлять сообщения журнала от всех задач сельдерея в один файл

Мне интересно, как настроить более конкретную систему ведения журнала. Все мои задачи используют

logger = logging.getLogger(__name__)

как общемодульный регистратор.

Я хочу, чтобы сельдерей регистрировался в «celeryd.log», а мои задачи - в «tasks.log», но я понятия не имел, как заставить это работать. Используя CELERYD_LOG_FILE из django-celery, я могу направить все сообщения журнала, связанные с celeryd, в celeryd.log, но нет никаких следов сообщений журнала, созданных в моих задачах.


person Community    schedule 31.05.2011    source источник


Ответы (3)


Примечание. Этот ответ устарел в Celery 3.0, где теперь вы используете get_task_logger(), чтобы настроить журнал для каждой задачи. См. раздел «Ведение журнала» документа «Что нового в Celery 3.0». для получения дополнительной информации.


В Celery есть специальная поддержка ведения журнала для каждой задачи. См. документацию по заданию по этой теме:

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

@celery.task()
def add(x, y):
    logger = add.get_logger()
    logger.info("Adding %s + %s" % (x, y))
    return x + y

Доступно несколько уровней ведения журнала, и настройка уровня журнала рабочих решает, будут ли они записаны в файл журнала.

Конечно, вы также можете просто использовать print, поскольку все, что написано в стандартном out / -err, также будет записано в файл журнала.

Под капотом это все еще стандартный модуль ведения журнала Python. Вы можете установить для параметра CELERYD_HIJACK_ROOT_LOGGER значение Значение false, чтобы разрешить работу вашей собственной настройки ведения журнала, в противном случае Celery настроит обработку за вас.

Однако для задач вызов .get_logger() позволяет создать отдельный файл журнала для каждой отдельной задачи. Просто передайте аргумент logfile, и он направит сообщения журнала в этот отдельный файл:

@celery.task()
def add(x, y):
    logger = add.get_logger(logfile='tasks.log')
    logger.info("Adding %s + %s" % (x, y))
    return x + y 

И последнее, но не менее важное: вы можете просто настроить свой пакет верхнего уровня в модуле ведения журнала Python. и дайте ему собственный обработчик файлов. Я бы установил это с помощью сигнала celery.signals.after_setup_task_logger; здесь я предполагаю, что все ваши модули находятся в пакете с именем foo.tasks (как в foo.tasks.email и foo.tasks.scaling):

from celery.signals import after_setup_task_logger
import logging

def foo_tasks_setup_logging(**kw):
    logger = logging.getLogger('foo.tasks')
    if not logger.handlers:
        handler = logging.FileHandler('tasks.log')
        formatter = logging.Formatter(logging.BASIC_FORMAT) # you may want to customize this.
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        logger.propagate = False

after_setup_task_logger.connect(foo_tasks_setup_logging)

Теперь для любого регистратора, имя которого начинается с foo.tasks, все сообщения будут отправляться на tasks.log, а не в корневой регистратор (который не видит ни одного из этих сообщений, потому что .propagate имеет значение False).

person Martijn Pieters    schedule 31.05.2011
comment
Буферизированы или не буферизированы сообщения журнала? Мне интересно, являются ли сообщения журнала о нарушении порядка показателем того, что задачи выполняются не по порядку. - person Eric Walker; 11.10.2014
comment
@EricWalker: logging ничего не буферизует. FileHandler использует обычный open() вызов, и по умолчанию файл открывается в текстовом режиме, поэтому при записи в него будет использоваться буферизация строк (сброс после каждой новой строки, что означает каждую запись в журнале). - person Martijn Pieters; 11.10.2014
comment
Кажется, есть опечатка в CELERYD_HIJACK_ROOT_LOGGER (а не в CELERY_HIJACK_ROOT_LOGGER) - person matt; 01.02.2017
comment
@imbolc: Я не могу найти никаких ссылок на CELERY_WORKER_HIJACK_ROOT_LOGGER, не уверен, что вы здесь говорите. Есть только CELERYD_HIJACK_ROOT_LOGGER и worker_hijack_root_logger имя параметра конфигурации (последнее является версией первого в нижнем регистре 4.x). - person Martijn Pieters; 28.10.2018
comment
@MartijnPieters да, это примерно 4.x, вам просто нужно сделать его префиксом и верхним регистром, чтобы использовать в settings.py - person imbolc; 28.10.2018
comment
@imbolc: этот ответ, однако, касается гораздо более старой версии Celery. Ничего из этого не относится к Celery 4. - person Martijn Pieters; 28.10.2018
comment
@MartijnPieters Я согласен, что TS вряд ли спрашивал о будущих выпусках :) Но люди, приходящие сюда в настоящее время, вероятно, работают с современными версиями. - person imbolc; 28.10.2018
comment
@imbolc: да, и для этих версий вы должны использовать get_task_logger, как указано вверху. - person Martijn Pieters; 28.10.2018

Подсказка: у Celery есть собственный обработчик журналов:

from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)

Кроме того, Celery регистрирует весь вывод задачи. Дополнительные сведения см. В документации Celery для ведения журнала задач.

person kolypto    schedule 21.08.2014

присоединиться к --concurrency=1 --loglevel=INFO с командой для запуска сельдерея

eg: python xxxx.py celery worker --concurrency=1 --loglevel=INFO

Лучше также установить уровень журнала внутри каждого файла python

person Sreenath P    schedule 01.11.2019