目前,我的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文档,但这似乎也没有效果。
答案 0 :(得分:0)
from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)
如果Celery工作人员在函数内调用logger.xxxx()
,则将使用Celery配置的logger
;否则,它将是手动配置的。该行为与函数所属的位置无关。