将所有celery任务的日志消息发送到一个文件

69 投票
3 回答
68989 浏览
提问于 2025-04-16 18:42

我在想怎么设置一个更具体的日志系统。我的所有任务都使用

logger = logging.getLogger(__name__)

作为模块级的日志记录器。

我希望celery能把日志记录到"celeryd.log"文件里,而我的任务日志记录到"tasks.log"文件里,但我不知道怎么实现这个。通过使用CELERYD_LOG_FILE这个设置,我可以把所有与celeryd相关的日志信息发送到celeryd.log,但我在我的任务中生成的日志信息却没有任何记录。

3 个回答

1

使用命令来启动celery工作进程时,可以加上

--concurrency=1 --loglevel=INFO

比如说,你可以这样写:

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

最好在每个Python文件里面也设置一下日志等级。

8

给你一个小提示:Celery有自己专门的日志处理工具:

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

另外,Celery会记录任务的所有输出。想了解更多,可以查看Celery的任务日志文档

103

注意:这个回答在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,因为任何写入标准输出或标准错误的信息也会被写入日志文件。

实际上,这一切仍然是标准的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.emailfoo.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)。

撰写回答