CELERY 4.0.2 不登录文件

Posted

技术标签:

【中文标题】CELERY 4.0.2 不登录文件【英文标题】:CELERY 4.0.2 doesn't log into the file 【发布时间】:2017-12-22 22:32:54 【问题描述】:

我在我的 Django 项目中使用 Celery (celery==4.0.2)。问题是我无法让 Celery 登录到文件中。我什么都试过了。唯一可行的是在命令中指定文件:

celery worker -A realestate_scanner -l info --purge --logfile=logs/celery.log

但问题是日志会变得非常大,所以我需要指定旋转记录器,并且我想在生产中运行 worker 和 beat 作为守护进程。

realestate_scanner/realestate_scanner/celery.py

from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'realestate_scanner.settings')
app = Celery('realestate_scanner')


app.config_from_object('django.conf:settings',)
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

realestate_scanner/realestate_scanner/settings.py ...

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'djmoney',
'storage',
'engineapp',
'presentation',
'import_export'
 ]


BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/Bratislava'
CELERY_LOG_FILE = 'test.log' # Not working
worker_log_file = 'test.log' # Not working

worker_hijack_root_logger = False

LOGGING =  # Not working
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': 
        'simple': 
            'format': '%(levelname)s %(message)s',
            'datefmt': '%y %b %d, %H:%M:%S',
        ,
    ,
    'handlers': 
        'console': 
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        ,
        'celery': 
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/celery.log',
            'formatter': 'simple',
            'maxBytes': 1024 * 1024 * 100,  # 100 mb
        ,
        'scrapy': 
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(BASE_DIR, 'logs/scrapy.log'),
            'formatter': 'simple'
        
    ,
    'loggers': 
        'celery': 
            'handlers': ['celery',],
            'level': 'INFO',
        ,
        'scrapy': 
            'handlers': ['scrapy'],
            'level': 'INFO',
        
    ,



from logging.config import dictConfig

dictConfig(LOGGING)

你有什么建议吗?

编辑:

根据lapinkoira 的回答,我已将此信号添加到celery.py 文件中:

from __future__ import absolute_import
import os

import logging
from celery import Celery
from django.conf import settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'realestate_scanner.settings')
app = Celery('realestate_scanner')


app.config_from_object('django.conf:settings',)
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

import celery.signals

@celery.signals.setup_logging.connect
def on_celery_setup_logging(**kwargs):
    logger = logging.getLogger('realestate_scanner.realestate_scanner.celery')
    if not logger.handlers:
        handler = logging.FileHandler('celery_test_log.log')
        formatter = logging.Formatter(logging.BASIC_FORMAT)  # you may want to customize this.
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        logger.propagate = False

信号可能有效,因为创建了 celery_test_log.log 文件,但输出再次进入 celery 控制台。

我可能没有得到我需要的记录器,但不知道如何得到它。

【问题讨论】:

你有哪个 celery 版本? @lapinkoira celery==4.0.2 啊我没看到你已经发布了上面的版本,你用主管守护工人吗? 目前还没有,它在我个人的 Ubuntu 上,但我想将它部署在 VPS 上,所以我会守护它,我希望今天 :) 【参考方案1】:

嗯,看起来像 celery dev 说 celery 仍然会配置它自己的记录器并忽略其他配置,即使你禁用 hijack_root_logger

他建议使用 celery 记录信号:

来源https://github.com/celery/celery/issues/3428

import celery.signals

@celery.signals.setup_logging.connect
def on_celery_setup_logging(**kwargs):
    pass

【讨论】:

我理解信号,但我不知道我应该在函数内部做什么。如何在那里设置日志记录?谢谢 你必须在信号中调用你的记录器处理程序,就像这个答案***.com/questions/6192265/… 我已经检查过并尝试创建信号。但我不知道如何获得正确的记录器。我在问题的底部添加了我的代码。 这很奇怪,但是在这样做之后,settings.py LOGGING 开始工作。即使在移除信号后也能正常工作。 @MilanoSlesarik - 你好,最后你是怎么做到的?【参考方案2】:

我找不到完整的答案,所以这是我的。

Django LOGGING 设置:

LOGGING = 
    ...
    'handlers': 
        'celery.file': 
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': "path/to/celery.log",
        ,
    ,
    'loggers': 
        'celery': 
            'handlers': ['celery.file'],
            'level': 'INFO',
        ,
    ,

我必须将记录器命名为 celery 才能正常工作。 myapp.celery 之类的名称不起作用。

celery.py:

import logging
import celery

...

@celery.signals.setup_logging.connect  
def setup_celery_logging(**kwargs):  
    return logging.getLogger('celery')  

如果您想在出现错误时向管理员发送电子邮件,只需像往常一样添加处理程序。

LOGGING = 
    ...
    'loggers': 
        'celery': 
            'handlers': ['celery.file', 'mail_admins'],
            'level': 'INFO',
        ,
    ,

【讨论】:

以上是关于CELERY 4.0.2 不登录文件的主要内容,如果未能解决你的问题,请参考以下文章

Django / Celery中的哨兵登录停止工作

Celery-Beat:ACCESS_REFUSED - 使用身份验证机制 AMQPLAIN 拒绝登录

Django+Celery+Redis 使用

celery 未处理的 celery 任务

python:利用celery分布任务

celery异步,延时任务, 周期任务