将所有 celery 任务的日志消息发送到单个文件
Posted
技术标签:
【中文标题】将所有 celery 任务的日志消息发送到单个文件【英文标题】:Send log messages from all celery tasks to a single file 【发布时间】:2011-09-05 17:49:19 【问题描述】:我想知道如何设置更具体的日志记录系统。我所有的任务都使用
logger = logging.getLogger(__name__)
作为模块范围的记录器。
我希望 celery 记录到“celeryd.log”,我的任务记录到“tasks.log”,但我不知道如何让它工作。使用 django-celery 中的CELERYD_LOG_FILE
,我可以将所有与 celeryd 相关的日志消息路由到 celeryd.log,但我的任务中创建的日志消息没有任何痕迹。
【问题讨论】:
【参考方案1】:注意:这个答案在 Celery 3.0 中已经过时了,你现在使用get_task_logger()
来设置你的每任务记录器。详情请见the Logging section of the What's new in Celery 3.0 document。
Celery 专门支持每个任务的日志记录。见Task documentation on the subject:
您可以使用工作人员记录器将诊断输出添加到工作人员日志:
@celery.task() def add(x, y): logger = add.get_logger() logger.info("Adding %s + %s" % (x, y)) return x + y
有多个日志级别可用,worker loglevel 设置决定 是否将它们写入日志文件。
当然,您也可以简单地使用 print,因为任何写入标准输出/-err 的内容都将是 也写入日志文件。
在底层,这仍然是标准的 python 日志记录模块。您可以将 CELERYD_HIJACK_ROOT_LOGGER
option 设置为 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 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
为假,根记录器看不到任何这些消息)。
【讨论】:
日志消息是缓冲的还是非缓冲的?我想知道无序的日志消息是否表明任务执行无序。 @EricWalker:logging
不缓冲任何东西。 FileHandler
使用常规的 open()
调用,默认以文本模式打开文件,因此写入该文件将使用行缓冲(在每个换行符之后刷新,这意味着每个日志条目)。
似乎“CELERYD_HIJACK_ROOT_LOGGER”(而不是“CELERY_HIJACK_ROOT_LOGGER”)中有错字
@imbolc:我找不到对CELERY_WORKER_HIJACK_ROOT_LOGGER
的任何引用,不确定你在说什么。只有CELERYD_HIJACK_ROOT_LOGGER
和worker_hijack_root_logger
配置选项名(后者是前者的4.x小写版本)。
@MartijnPieters 是的,它大约是 4.x,您只需将其设为前缀和大写即可在 settings.py
中使用【参考方案2】:
提示:Celery 有自己的日志处理程序:
from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)
此外,Celery 记录任务的所有输出。更多详情Celery docs for Task Logging
【讨论】:
【参考方案3】:加入
--concurrency=1 --loglevel=INFO
用命令运行 celery worker
例如:python xxxx.py celery worker --concurrency=1 --loglevel=INFO
最好在每个 python 文件中设置日志级别
【讨论】:
以上是关于将所有 celery 任务的日志消息发送到单个文件的主要内容,如果未能解决你的问题,请参考以下文章