web-dev-qa-db-fra.com

Envoyer des messages de journal de toutes les tâches de céleri dans un seul fichier

Je me demande comment configurer un système de journalisation plus spécifique. Toutes mes tâches utilisent

logger = logging.getLogger(__name__)

comme enregistreur à l'échelle du module.

Je veux que le céleri se connecte à "celeryd.log" et mes tâches à "tasks.log" mais je ne sais pas comment faire fonctionner cela. En utilisant CELERYD_LOG_FILE de Django-celery Je peux router tous les messages de journaux liés à celeryd vers celeryd.log mais il n'y a aucune trace des messages de journaux créés dans mes tâches.

64
user816328

Remarque: Cette réponse est obsolète à partir de Celery 3.0, où vous utilisez maintenant get_task_logger() pour configurer votre enregistreur par tâche. Veuillez consulter la section Journalisation du document Quoi de neuf dans Celery 3. pour plus de détails.


Celery a un support dédié pour la journalisation, par tâche. Voir le Documentation des tâches sur le sujet :

Vous pouvez utiliser le journal des travailleurs pour ajouter une sortie de diagnostic au journal des travailleurs:

@celery.task()
def add(x, y):
    logger = add.get_logger()
    logger.info("Adding %s + %s" % (x, y))
    return x + y

Plusieurs niveaux de journalisation sont disponibles et le paramètre de niveau de journalisation des travailleurs décide s'ils seront ou non écrits dans le fichier journal.

Bien sûr, vous pouvez également simplement utiliser l'impression car tout ce qui est écrit sur la sortie/-err standard sera également écrit dans le fichier journal.

Sous le capot, tout cela est toujours le module de journalisation standard python. Vous pouvez définir CELERYD_Hijack_ROOT_LOGGER Option sur False pour permettre à votre propre configuration de journalisation de fonctionner , sinon Celery configurera la gestion pour vous.

Cependant, pour les tâches, l'appel .get_logger() vous permet de configurer un fichier journal distinct pour chaque tâche individuelle. Passez simplement un argument logfile et il acheminera les messages du journal vers ce fichier séparé:

@celery.task()
def add(x, y):
    logger = add.get_logger(logfile='tasks.log')
    logger.info("Adding %s + %s" % (x, y))
    return x + y 

Enfin et surtout, vous pouvez simplement configurer votre package de niveau supérieur dans le module de journalisation python et lui donner son propre gestionnaire de fichiers. Je configurerais ceci en utilisant le signal celery.signals.after_setup_task_logger; ici, je suppose que tous vos modules vivent dans un package appelé foo.tasks (comme dans foo.tasks.email et foo.tasks.scaling):

from celery.signals import after_setup_task_logger
import logging

def foo_tasks_setup_logging(**kw):
    logger = logging.getLogger('foo.tasks')
    if not logger.handlers:
        handler = logging.FileHandler('tasks.log')
        formatter = logging.Formatter(logging.BASIC_FORMAT) # you may want to customize this.
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        logger.propagate = False

after_setup_task_logger.connect(foo_tasks_setup_logging)

Désormais, tout enregistreur dont le nom commence par foo.tasks Verra tous ses messages envoyés à tasks.log Au lieu de l'enregistreur racine (qui ne voit aucun de ces messages car .propagate Est Faux).

101
Martijn Pieters

Juste un indice: Celery a son propre gestionnaire de journalisation:

from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)

De plus, Celery enregistre toutes les sorties de la tâche. Plus de détails sur Celery docs for Task Logging

5
kolypto