我的celery任务不会在每次致电logger.critical时向应用程序管理员发送电子邮件。
我正在构建Django应用程序。我项目的当前配置允许每次创建logger.critical消息时,应用程序的管理员都可以接收电子邮件。设置起来非常简单,我只是遵循了两个项目(celery和Django)的文档。出于某种原因(我不确定),在celery任务中运行的代码没有相同的行为,它不会在每次创建logger.critical消息时向应用程序管理员发送电子邮件。 / p>
芹菜实际上是否允许这样做? 我是否缺少某些配置? 有谁遇到这个问题并能够解决?
使用:
感谢您的帮助。
答案 0 :(得分:6)
如文档所述,Celery会覆盖当前的日志记录配置以应用自己的日志记录,它还说您可以在Django设置中将CELERYD_HIJACK_ROOT_LOGGER
设置为False
来防止此行为,这不是很好有记载的是,目前这还行不通。
我认为您有2种选择:
setup_logging
信号(确实)覆盖您的配置打开您的celery.py
文件并添加以下内容:
from celery.signals import setup_logging
@setup_logging.connect
def config_loggers(*args, **kwags):
pass
之后,您的文件应大致如下所示:
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from celery.signals import setup_logging
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
@setup_logging.connect
def config_loggers(*args, **kwags):
pass
但是除非您有充分的理由,否则我将避免使用此选项,因为这样一来,您将丢失由Celery处理的默认任务日志记录,这是非常不错的。
您可以在Django LOGGING
配置中定义一个自定义记录器,并在您的任务中使用它,例如:
Django设置:
LOGGING = {
# ... other configs ...
'handlers': {
'my_email_handler': {
# ... handler configuration ...
},
},
'loggers': {
# ... other loggers ...
'my_custom_logger': {
'handlers': ['my_email_handler'],
'level': 'CRITICAL',
'propagate': True,
},
},
}
任务:
import logging
logger = logging.getLogger('my_custom_logger')
@shared_task
def log():
logger.critical('Something bad happened!')
我相信这是最适合您的方法,因为据我了解,您需要手动记录消息,这使您可以继续使用Celery记录系统。
答案 1 :(得分:-3)
来自Celery文档:
默认情况下,根记录器上所有先前配置的处理程序都将被删除。如果要自定义自己的日志处理程序,则可以通过设置worker_hijack_root_logger = False来禁用此行为。
Celery安装了自己的记录器,您可以使用get_task_logger()
调用获得该记录器。我假设您编写了自己的记录器,该记录器执行了原始问题中描述的逻辑。阅读有关Celery logging的更多信息,以了解如何禁用此行为并根据您的需要调整Celery。