Ответ 1
Примечание. Этот ответ устарел от Celery 3.0, где теперь вы используете get_task_logger()
, чтобы настроить свой логгер для каждой задачи, Подробнее см. раздел журнала в разделе Что нового в документе Celery 3.0.
Сельдерей имеет специальную поддержку для ведения журнала, для каждой задачи. См. Документация по объекту:
Вы можете использовать регистратор рабочих данных для добавления диагностического вывода в журнал работника:
@celery.task() def add(x, y): logger = add.get_logger() logger.info("Adding %s + %s" % (x, y)) return x + y
Доступно несколько уровней ведения журналов, и параметр loglevel рабочих определяется независимо от того, будут ли они записаны в файл журнала.
Конечно, вы также можете просто использовать печать, поскольку все, что написано на стандартном выводе /-err, будет также записывается в файл журнала.
Под капотом это все еще стандартный протокол протоколирования python. Вы можете установить параметр CELERYD_HIJACK_ROOT_LOGGER
для False, чтобы разрешить работу вашей собственной настройки ведения журнала, в противном случае сельдерей настроит обработку для вас.
Однако для задач вызов .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 logging module и предоставить ему обработчик файлов своя. Я бы установил это с помощью сигнала 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).