web-dev-qa-db-fra.com

Python - Comment vider le journal? (Django)

Je travaille avec Django-nonrel sur Google App Engine, ce qui m'oblige à utiliser logging.debug () au lieu de print ().

Le module "logging" est fourni par Django, mais j'ai du mal à l'utiliser au lieu de print ().

Par exemple, si je dois vérifier le contenu de la variable x, je mettrai
logging.debug('x is: %s' % x). Mais si le programme se bloque peu de temps après (sans vider le flux), il n'est jamais imprimé.

Donc, pour le débogage, j'ai besoin que debug () soit vidé avant que le programme ne se termine en cas d'erreur, et cela ne se produit pas.

26
Rucent88

Je pense que cela peut fonctionner pour vous, en supposant que vous n'utilisez qu'un seul (ou par défaut) gestionnaire:

>>> import logging
>>> logger = logging.getLogger()
>>> logging.debug('wat wat')
>>> logger.handlers[0].flush()

C'est un peu mal vu dans la documentation, cependant.

Le code d'application ne doit pas instancier directement et utiliser des instances de Handler. Au lieu de cela, la classe Handler est une classe de base qui définit l'interface que tous les gestionnaires doivent avoir et établit un comportement par défaut que les classes enfants peuvent utiliser (ou remplacer). http://docs.python.org/2/howto/logging.html#handler-basic

Et cela pourrait être une perte de performances, mais si vous êtes vraiment bloqué, cela peut vous aider avec votre débogage.

15
Mike Shultz

Si le cas d'utilisation est que vous avez un programme python qui devrait vider ses journaux à la fermeture, utilisez logging.shutdown().

De la documentation python:

logging.shutdown ()

Indique au système de journalisation d'effectuer un arrêt ordonné en vidant et fermant tous les gestionnaires. Cela doit être appelé à la sortie de l'application et aucune autre utilisation du système de journalisation ne doit être effectuée après cet appel.

10
Risadinha

J'ai lutté avec un problème similaire et voici comment je l'ai résolu. Au lieu d'utiliser le module logging directement pour générer vos journaux, initialisez votre propre enregistreur comme suit:

import sys
import logging


def init_logger():
    logger = logging.getLogger()

    h = logging.StreamHandler(sys.stdout)
    h.flush = sys.stdout.flush
    logger.addHandler(h)

    return logger

Ensuite, utilisez-le à la place de logging dans votre code:

def f():
    logger = init_logger()
    logger.debug('...')

Par conséquent, vous n'aurez plus de problèmes avec le vidage des journaux.

9
constt

La journalisation de Django repose sur le module de journalisation standard python.

Ce module a une méthode au niveau du module: logging.shutdown() qui vide tous les gestionnaires et arrête le système de journalisation (c'est-à-dire que la journalisation ne peut plus être utilisée après son appel)

L'inspection du code de cette fonction montre qu'actuellement (python 2.7) le module de journalisation contient une liste de références faibles à tous les gestionnaires dans une variable de niveau module appelée _handlerList afin que tous les gestionnaires puissent être vidés en faisant quelque chose comme

[h_weak_ref().flush() for h_weak_ref in logging._handlerList]

car cette solution utilise les internes du module @Mikes la solution ci-dessus est meilleure, mais elle repose sur l'accès à un logger, elle peut être généralisée comme suit:

 [h.flush() for h in my_logger.handlerList]
5
tjb