【问题标题】:Send log messages from all celery tasks to a single file将所有 celery 任务的日志消息发送到单个文件
【发布时间】:2011-09-05 17:49:19
【问题描述】:

我想知道如何设置更具体的日志记录系统。我所有的任务都使用

logger = logging.getLogger(__name__)

作为模块范围的记录器。

我希望 celery 记录到“celeryd.log”,我的任务记录到“tasks.log”,但我不知道如何让它工作。使用 django-celery 中的CELERYD_LOG_FILE,我可以将所有与 celeryd 相关的日志消息路由到 celeryd.log,但我的任务中创建的日志消息没有任何痕迹。

【问题讨论】:

    标签: python logging celery


    【解决方案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.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 为假,根记录器看不到任何这些消息)。

    【讨论】:

    • 日志消息是缓冲的还是非缓冲的?我想知道无序的日志消息是否表明任务执行无序。
    • @EricWalker:logging 不缓冲任何东西。 FileHandler 使用常规的 open() 调用,默认以文本模式打开文件,因此写入该文件将使用行缓冲(在每个换行符之后刷新,这意味着每个日志条目)。
    • 似乎“CELERYD_HIJACK_ROOT_LOGGER”(而不是“CELERY_HIJACK_ROOT_LOGGER”)中有错字
    • @imbolc:我找不到对CELERY_WORKER_HIJACK_ROOT_LOGGER 的任何引用,不确定你在说什么。只有CELERYD_HIJACK_ROOT_LOGGERworker_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 文件中设置日志级别

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-15
        • 1970-01-01
        • 2012-07-29
        • 2013-09-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多