Celery记录器配置

use*_*391 6 python django logging celery

我正在使用Django 1.10,python 3.5和celery 4.1.0,我正在尝试将celery任务信息记录到文件中。所以我按照芹菜文档中的建议进行了尝试-

from celery.utils.log import get_task_logger

logger = get_task_logger(__name__)
Run Code Online (Sandbox Code Playgroud)

并尝试在任务内记录一条消息-

logger.info(message)
Run Code Online (Sandbox Code Playgroud)

我希望它可以登录到我的默认记录器。但事实并非如此。因此,我在设置中添加了一个名为“ celery.task”的专用记录器(据文档了解):

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
    'require_debug_false': {
        '()': 'django.utils.log.RequireDebugFalse',
    },
    'require_debug_true': {
        '()': 'django.utils.log.RequireDebugTrue',
    },
    'require_test_false': {
        '()': 'myapp.utils.classes.logging.RequireTestFalse',
    },
    'suppress_deprecated': {
        '()': 'myapp.utils.classes.logging.SuppressDeprecated'
    }
},
'handlers': {
    'console': {
        'level': 'INFO',
        'class': 'logging.StreamHandler',
        'formatter': 'json',
        'filters': ['suppress_deprecated']
    },
    'celery_file': {
        'level': 'INFO',
        'class': 'myapp.utils.classes.logging.SBRotatingFileHandler',
        'maxBytes': 1024 * 1024 * 200,  # 200 MB
        'backupCount': 10,
        'formatter': 'json',
        'filename': BASE_DIR + '/../log/celery.log',
    }
},
'loggers': {
    'django': {
        'handlers': ['console', 'file'],
        'level': LOG_LEVEL,
        'propagate': True,
    },
    'celery.task': {
        'handlers': ['console', 'celery_file'],
        'level': 'INFO',
        'propagate': True,
            },
}
Run Code Online (Sandbox Code Playgroud)

但是我仍然没有在celery.log文件或默认日志文件中都看不到celery任务的日志。

仅当以'-f'启动celery worker时-它将日志写入该文件有什么想法?

编辑:我试图使用'after_setup_task_logger'更新celery.task logger处理程序,以成功使用我的logging.config(在设置中)存在的处理程序。我尝试了以下方法:

 @celery.signals.after_setup_task_logger.connect
 def after_setup_logging(logger, **kwargs):
     logging_settings = settings.LOGGING
     celery_handler = logging_settings['handlers']['celery_file']
     logger.addHandler(celery_handler)
Run Code Online (Sandbox Code Playgroud)

但这是行不通的。我越来越

AttributeError: 'dict' object has no attribute 'createLock'
Run Code Online (Sandbox Code Playgroud)

这意味着未正确创建处理程序。因此,我尝试从“记录”对象中获取处理程序。但是我在logging._handlers和logging._handlersList中都看不到我的处理程序

更新:那终于对我有用:

def create_celery_logger_handler(logger, propagate):
    # 209715200 is 1024 * 1024 * 200 or 200 MB, same as in settings
    celery_handler = RotatingFileHandler(
        settings.CELERY_LOG_FILE,
        maxBytes=209715200,
        backupCount=10
    )
    celery_formatter = jsonlogger.JsonFormatter(settings.LOGGING['formatters']['json']['format'])
    celery_handler.setFormatter(celery_formatter)

    logger.addHandler(celery_handler)
    logger.logLevel = settings.LOG_LEVEL
    logger.propagate = propagate


@celery.signals.after_setup_task_logger.connect
def after_setup_celery_task_logger(logger, **kwargs):
    """ This function sets the 'celery.task' logger handler and formatter """
    create_celery_logger_handler(logger, True)


@celery.signals.after_setup_logger.connect
def after_setup_celery_logger(logger, **kwargs):
    """ This function sets the 'celery' logger handler and formatter """
    create_celery_logger_handler(logger, False)
Run Code Online (Sandbox Code Playgroud)

cha*_*der 9

对于它的价值,这是我配置celery以使用Django日志记录设置的方式:

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from celery.signals import setup_logging

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

app = Celery('app')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

@setup_logging.connect
def config_loggers(*args, **kwags):
    from logging.config import dictConfig
    from django.conf import settings
    dictConfig(settings.LOGGING)

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
Run Code Online (Sandbox Code Playgroud)

就是这样-更改之后,我的Django日志记录设置适用于芹菜,包括我已设置为将日志消息发送到松弛状态的日志记录。


geo*_*xsh 6

默认情况下,芹菜会重置左撇子celery.task记录,您可以禁用这种行为worker_hijack_root_logger选项。或者,您可以在after_setup_task_logger信号中重新配置此记录器,甚至不要让 celery 使用setup_logging信号配置记录器:

from celery.signals import setup_logging

@setup_logging.connect()
def config_loggers(*args, **kwargs):
    from logging.config import dictConfig
    dictConfig(app.config['LOGGING_CONFIG'])
Run Code Online (Sandbox Code Playgroud)

  • @user2880391 为什么不设置`worker_hijack_root_logger = False`,IMO 是一个更明智的解决方案。 (2认同)