Celery + Django - 如何记录非任务模块

时间:2015-09-27 20:00:42

标签: python django celery

目前,我的Django + Docker-Compose项目能够使用Celery来创建主要上传功能insertIntoDatabase,这是一个在后台正常运行的异步任务。我使用名为worker的Docker容器运行Celery,我可以在控制台中看到它的日志。但是,现在不再发生insertIntoDatabase中通常有效的日志记录。

views.py开始上传:

from .tasks import db_ins_task
...
db_ins_task.delay(datapoints, user, description) # datapoints is a list of dictionaries, user and description are simple strings

任务在tasks.py

中定义
@app.task()
def db_ins_task(datapoints, user, description):
    from utils.db.databaseinserter import insertIntoDatabase
    insertIntoDatabase(datapoints, user, description)

因此,在databaseinserter.py中,以下日志记录不再有效:

logger = logging.getLogger('myapp.databaseinserter')
...
def insertIntoDatabase(datapoints, user, description):
    # do the database insertion work
    ...
    logger.info("This upload took %.3g seconds", elapsed_time) 

最后的信息日志应该转到我在settings.py中配置的日志文件。现在从任务而不是直接调用insertIntoDatabase,此类信息日志不再出现在正确的日志文件中。我项目中存在的所有其他日志记录仍然可以正常工作。我该怎么做才能使记录再次工作?

如需进一步参考,此处是名为celery.py的单独应用中taskman的一部分:

from __future__ import absolute_import
import os
from django.apps import AppConfig
from celery import Celery, Task

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproj.settings')

from django.conf import settings

app = Celery('myproj')
class CeleryConfig(AppConfig):
    name = 'taskman'
    verbose_name = 'Celery Config'

    def ready(self):
        app.config_from_object('django.conf:settings')
        app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

以下是settings.py中日志记录设置的相关部分:

LOGGING = {
    ...
    'handlers' = {
    ...
        'dbinsfile': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'maxBytes':LOG_LIMIT,
            'backupCount':10,
            'filename':'logs/insvals.log',
            'formatter':'values',
        },
    ...

    },
    'formatters' = {
    ...
        'values': {
            'format':'>>> [%(asctime)s.%(msecs)03d] %(levelname)s: %(message)s',
            'datefmt':"%Y/%m/%d %H:%M:%S",
        },
    ...
    },
    'loggers' = {
    ...
        'myapp.databaseinserter': {
            'handlers':['dbinsfile'],
            'level':'DEBUG',
            'propagate':False,
        },
    ...
    }
}

编辑: 我认为问题在于Celery似乎在劫持根级记录器,或类似的东西。我已经尝试了CELERYD_HIJACK_ROOT_LOGGER = False,但遗憾的是它没有改变任何东西。我还尝试将以下内容添加到settings.py

from celery.signals import setup_logging
@setup_logging.connect
def logging_prevent_celery_hijack(loglevel, logfile, format, colorize, **kwargs):
    import logging.config
    logging.config.dictConfig(LOGGING)

关于信号和日志记录的Celery文档,但这似乎也没有效果。

1 个答案:

答案 0 :(得分:0)

来自the official document

from celery.utils.log import get_task_logger

logger = get_task_logger(__name__)

如果Celery工作人员在函数内调用logger.xxxx(),则将使用Celery配置的logger;否则,它将是手动配置的。该行为与函数所属的位置无关。