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

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

logger = logging.getLogger(__name__)

в качестве регистратора всего модуля.

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

64
задан 9 October 2014 в 17:37
поделиться

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 является Ложным).

101
ответ дан 24 November 2019 в 15:54
поделиться

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

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

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

6
ответ дан 24 November 2019 в 15:54
поделиться

соединение --concurrency=1 --loglevel=INFO с командой для выполнения рабочего сельдерея

, например: python xxxx.py celery worker --concurrency=1 --loglevel=INFO

Лучше для установки loglevel в каждом Python файлы также

0
ответ дан 24 November 2019 в 15:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: