芹菜从 Django 模块内部记录到文件

Posted

技术标签:

【中文标题】芹菜从 Django 模块内部记录到文件【英文标题】:Celery logging to file from inside the Django modules 【发布时间】:2014-01-08 22:20:38 【问题描述】:

我的tasks.py中有以下内容

from celery.utils.log import get_task_logger
logger = get_task_logger("celery.task")

我在settings.py 中设置了celery.task 的日志记录,并且我的tasks.py 文件中的所有日志都已正确记录到文件中。

我有 Django 模块。这些模块可以直接从 Django 或通过 Celery 任务调用。我想要的是,如果模块被 Django 调用,那么日志应该转到 Django 日志文件。如果模块被任务调用,日志应该去 celery 任务记录器。

例子:

# tasks.py

from app.foo import MyFoo

@task(name="bar")
def boo():
    MyFoo.someFoo()

# app.foo.py

log = logging.getLogger(__name__)

我希望 MyFoo 中的日志消息在由工作任务运行时转到 celery 日志。

有什么想法吗?

【问题讨论】:

【参考方案1】:

您应该能够为 Django 进程和 Celery 进程分别配置记录器,就像根据定义它们在不同的进程中运行一样。

实际上我很惊讶日志输出没有转到单独的日志文件;因此,公开您已经存在的日志配置类型可能对您有意义。

Python 日志输出的去向由logging handlers 定义。

为 Django 配置记录器:https://docs.djangoproject.com/en/dev/topics/logging/

对于 Celery,似乎没有直接的方法来覆盖日志记录设置。他们似乎提供了一个celery.signals.setup_logging,您可以在其中设置断点,使用logging API 重新配置日志处理程序以转到单独的日志文件。

http://docs.celeryproject.org/en/latest/configuration.html#logging

或者,您可以在任务级别上提取不同的logger 对象。当你执行一个任务时,你知道它是从 Django (eager) 还是 Celery 执行的。

我自己从未这样做过,但显然 Celery 任务将任务运行上下文公开为 self.request 参数(与 Python 类无关)。

http://docs.celeryproject.org/en/latest/userguide/tasks.html#context

因此,在您的任务功能开始时,您可以在记录器之间切换:

# Define web_worker_logger
# Define task_logger

@task(name='example')
def moobar():
    logger = web_worker_logger if self.request.is_eager else task_logger

【讨论】:

谢谢,这会让我知道任务是否由工作人员运行。这不是我需要的。我已经更新了问题。 这可能是您需要的。因为在进入函数之前,你无法知道你是在 Clery 内部还是在 Django 内部运行。因此,这是您可以选择在本地使用哪个记录器的唯一点。 但是我建议你研究如何配置 Celery 记录器。因为 Celery worker 在单独的进程上运行,所以它有自己的配置文件,您可以在其中配置 Python 日志记录处理程序。 docs.python.org/2/library/logging.html#handler-objects 稍微更新了答案。

以上是关于芹菜从 Django 模块内部记录到文件的主要内容,如果未能解决你的问题,请参考以下文章

如何记录 Django 芹菜任务中发生的异常

芹菜登录 Django

开始芹菜:AttributeError:“模块”对象没有属性“芹菜”

芹菜 - 没有名为五的模块

Django 中 Python 日志记录的优雅设置

如何使用芹菜工人将 django 项目部署到谷歌云?