J'utilise la journalisation Python et, pour une raison quelconque, tous mes messages apparaissent deux fois.
J'ai un module pour configurer la journalisation:
# BUG: It's outputting logging messages twice - not sure why - it's not the propagate setting.
def configure_logging(self, logging_file):
self.logger = logging.getLogger("my_logger")
self.logger.setLevel(logging.DEBUG)
self.logger.propagate = 0
# Format for our loglines
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
# Setup console logging
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
self.logger.addHandler(ch)
# Setup file logging as well
fh = logging.FileHandler(LOG_FILENAME)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
self.logger.addHandler(fh)
Plus tard, j'appelle cette méthode pour configurer la journalisation:
if __== '__main__':
tom = Boy()
tom.configure_logging(LOG_FILENAME)
tom.buy_ham()
Et puis à l'intérieur, le module buy_ham, j'appellerais:
self.logger.info('Successfully able to write to %s' % path)
Et pour une raison quelconque, tous les messages apparaissent deux fois. J'ai commenté l'un des gestionnaires de flux, toujours la même chose. Un peu bizarre, je ne sais pas pourquoi cela se passe ... lol. En supposant que j'ai raté quelque chose d'évident.
A bientôt, Victor
Vous appelez deux fois configure_logging
(peut-être dans la méthode __init__
de Boy
): getLogger
renverra le même objet, mais addHandler
ne vérifie pas si un gestionnaire similaire a déjà été ajouté à l'enregistreur.
Essayez de suivre les appels de cette méthode et d’en éliminer une. Ou définissez un indicateur logging_initialized
initialisé à False
dans la méthode __init__
de Boy
et remplacez configure_logging
par ne rien faire si logging_initialized
est True
et définissez-le sur True
après avoir initialisé le consignateur.
Si votre programme crée plusieurs instances Boy
, vous devrez changer la façon dont vous procédez avec une fonction globale configure_logging
en ajoutant les gestionnaires, et la méthode Boy.configure_logging
n'initialisant que l'attribut self.logger
.
Une autre façon de résoudre ce problème consiste à vérifier l’attribut handlers de votre enregistreur:
logger = logging.getLogger('my_logger')
if not logger.handlers:
# create the handlers and call logger.addHandler(logging_handler)
Le gestionnaire est ajouté chaque fois que vous appelez de l'extérieur. Essayez de supprimer le gestionnaire après avoir terminé votre travail:
self.logger.removeHandler(ch)
Je suis un débutant en python, mais cela a semblé fonctionner pour moi (Python 2.7)
while logger.handlers:
logger.handlers.pop()
Si vous voyez ce problème et que vous n’ajoutez pas le gestionnaire deux fois, voyez la réponse d’abarnert ici
De la docs :
Remarque: Si vous associez un gestionnaire à un enregistreur et à un ou plusieurs de ses ancêtres, il peut émettre le même enregistrement plusieurs fois. En général, vous ne devrait pas avoir besoin d'attacher un gestionnaire à plus d'un enregistreur - si vous attachez-le simplement à l’enregistreur approprié qui se trouve le plus haut dans le Logger Logger, il verra tous les événements enregistrés par tous les descendants les enregistreurs, à condition que leur paramètre de propagation soit laissé défini sur True. UNE Le scénario courant consiste à attacher des gestionnaires uniquement à l'enregistreur racine et à laissez la propagation s'occuper du reste.
Donc, si vous voulez un gestionnaire personnalisé sur "test" et que vous ne voulez pas que ses messages soient également envoyés au gestionnaire racine, la réponse est simple: désactivez son indicateur de propagation:
logger.propagate = False
Un appel à logging.debug()
appelle logging.basicConfig()
si aucun gestionnaire racine n'est installé. Cela se passait pour moi dans un cadre de test où je ne pouvais pas contrôler l'ordre de renvoi des cas de test. Mon code d'initialisation installait le second. La valeur par défaut utilise logging.BASIC_FORMAT que je ne voulais pas.