Мне интересно, как настроить более конкретную систему ведения журнала. Все мои задачи используют
logger = logging.getLogger(__name__)
в качестве регистратора всего модуля.
Я хочу, чтобы сельдерей регистрировался в «celeryd.log», а мои задачи - в «tasks.log», но я понятия не имел, как это работает. Используя CELERYD_LOG_FILE
из django-celery, я могу маршрутизировать все celeryd связанные сообщения журнала с celeryd.log, но нет никаких следов сообщений журнала, созданных в моих задачах.
Примечание. Этот ответ устарел с версии 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
является Ложным).
Просто подсказка: у Celery есть свой собственный обработчик записи:
from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)
Кроме того, Celery записывает все выходные данные задачи. Более подробная информация в Документы Celery для ведения журнала задач
соединение --concurrency=1 --loglevel=INFO
с командой для выполнения рабочего сельдерея
, например: python xxxx.py celery worker --concurrency=1 --loglevel=INFO
Лучше для установки loglevel в каждом Python файлы также