web-dev-qa-db-fra.com

Configuration de l'enregistreur de céleri

J'utilise Django 1.10, python 3.5 et céleri 4.1.0 J'essaie de consigner les informations sur les tâches de céleri dans un fichier. J'ai donc essayé comme suggéré dans la documentation du céleri -

from celery.utils.log import get_task_logger

logger = get_task_logger(__name__)

et a essayé d'enregistrer un message dans la tâche -

logger.info(message)

Je m'attendais à ce qu'il se connecte à mon enregistreur par défaut. Mais ce n'était pas le cas. J'ai donc ajouté aux paramètres un enregistreur dédié nommé 'celery.task' (si je comprends bien de la documentation):

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,
            },
}

Mais je ne vois toujours pas les journaux de la tâche céleri, ni dans le fichier celery.log ni dans le fichier journal par défaut.

Uniquement lors du démarrage du céleri avec '-f' - il écrit les journaux dans ce fichier. Des idées?

EDIT: J'essaie d'utiliser 'after_setup_task_logger' pour mettre à jour le gestionnaire de journalisation celery.task pour utiliser un gestionnaire qui existe dans mon logging.config (dans les paramètres) sans succès. J'ai essayé ce qui suit:

 @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)

Mais ça ne marche pas. Je suis en train

AttributeError: 'dict' object has no attribute 'createLock'

Ce qui signifie que le gestionnaire n'a pas été correctement créé. J'ai donc essayé d'obtenir le gestionnaire à partir de l'objet "journalisation". Mais je ne vois pas mon gestionnaire à la fois dans logging._handlers et logging._handlersList

MISE À JOUR: C'est ce qui a finalement fonctionné pour moi:

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)
10
user2880391

Pour ce que ça vaut, voici comment j'ai configuré le céleri pour utiliser mes paramètres de journalisation 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()

C'était à ce sujet - après cette modification, mes paramètres de journalisation Django fonctionnaient pour le céleri, y compris la journalisation que j'avais configurée pour envoyer des messages de journal vers Slack.

12
chander

Par défaut, le céleri réinitialiser les gestionnaires le celery.task logger, vous pouvez désactiver ce comportement avec worker_Hijack_root_logger option . Ou, vous pouvez reconfigurer cet enregistreur dans le signal after_setup_task_logger , même ne laissez pas le céleri configurer les enregistreurs avec setup_logging signal:

from celery.signals import setup_logging

@setup_logging.connect()
def config_loggers(*args, **kwargs):
    from logging.config import dictConfig
    dictConfig(app.config['LOGGING_CONFIG'])
3
georgexsh

Je tripotais ma journalisation ce matin en essayant de comprendre pourquoi mon journal n'a pas été propagé à l'enregistreur racine, comme l'a révélé @georgexsh, celey détourne l'enregistreur racine, voici ma configuration de journal de travail:

'loggers': {
        'Django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        'cal': {
            'handlers': ['general'],
            'level': 'INFO',
            'propagate': True,
        },
        '': {
            'handlers': ['gelf'],
            'level': 'INFO',
        }
    }

Et avec CELERYD_Hijack_ROOT_LOGGER = False dans les paramètres.

Tous les journaux de céleri vont maintenant au graylog (défini à la racine) au lieu de l'emplacement habituel.

0
James Lin