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 __name__ == '__main__':
tom = Boy()
tom.configure_logging(LOG_FILENAME)
tom.buy_ham()
Et puis dans disons, 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 produit ... lol. En supposant que j'ai raté quelque chose d'évident.
Bravo, Victor
configure_logging()
n'est pas appelé deux fois (par exemple depuis le constructeur aussi)? Une seule instance de Boy () est-elle créée?self.logger.handlers = [ch]
place résoudrait ce problème, mais il serait préférable de vous assurer de ne pas exécuter ce code deux fois, par exemple en utilisantif not self.logger
au début.Réponses:
Vous appelez
configure_logging
deux fois (peut-être dans la__init__
méthode deBoy
):getLogger
renvoie le même objet, maisaddHandler
ne vérifie pas si un gestionnaire similaire a déjà été ajouté à l'enregistreur.Essayez de suivre les appels à cette méthode et d'éliminer l'un d'entre eux. Ou configurez un indicateur
logging_initialized
initialiséFalse
dans la__init__
méthode deBoy
et changezconfigure_logging
pour ne rien faire silogging_initialized
c'est le casTrue
, et pour le définirTrue
après avoir initialisé le logger.Si votre programme crée plusieurs
Boy
instances, vous devrez changer la façon dont vous faites les choses avec uneconfigure_logging
fonction globale ajoutant les gestionnaires, et laBoy.configure_logging
méthode initialisant uniquement l'self.logger
attribut.Une autre façon de résoudre ce problème consiste à vérifier l'attribut handlers de votre enregistreur:
la source
logger
variable utilisée n'était pas celle instanciée à partir d'une de mes classes, mais lalogger
variable présente sur le cache Python3 , et le gestionnaire a été ajouté toutes les 60 secondes par un AppScheduler que j'ai configuré. C'est doncif not logger.handlers
un moyen assez intelligent d'éviter ce type de phénomène. Merci pour la solution, camarade :)!Si vous rencontrez ce problème et que vous n'ajoutez pas deux fois le gestionnaire, consultez la réponse d'abarnert ici
À partir de la documentation :
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
propagate
indicateur:la source
Le gestionnaire est ajouté chaque fois que vous appelez de l'extérieur. Essayez de supprimer le gestionnaire après avoir terminé votre travail:
la source
logger.handlers.pop()
en python 2.7, fait l'affaireJe suis un débutant en python, mais cela a semblé fonctionner pour moi (Python 2.7)
la source
Dans mon cas, je devrais régler
logger.propagate = False
pour éviter la double impression.Dans le code ci-dessous, si vous supprimez,
logger.propagate = False
vous verrez une double impression.la source
logger.propagate = False
était la solution pour éviter la double journalisation dans une application Flask hébergée par Waitress, lors de la connexion à l'app.logger
instance de Flask .Un appel aux
logging.debug()
appelslogging.basicConfig()
s'il n'y a pas de gestionnaire racine installé. Cela se passait pour moi dans un cadre de test où je ne pouvais pas contrôler l'ordre dans lequel les cas de test étaient déclenchés. Mon code d'initialisation installait le second. La valeur par défaut utilise logging.BASIC_FORMAT que je ne voulais pas.la source
Il semble que si vous envoyez quelque chose à l'enregistreur (accidentellement) puis le configurez, il est trop tard. Par exemple, dans mon code j'avais
J'obtiendrais quelque chose comme (en ignorant les options de format)
et tout a été écrit deux fois sur stdout. Je pense que c'est parce que le premier appel à
logging.warning
crée un nouveau gestionnaire automatiquement, puis j'ai explicitement ajouté un autre gestionnaire. Le problème a disparu lorsque j'ai supprimé le premierlogging.warning
appel accidentel .la source
J'avais une situation étrange où les journaux de la console étaient doublés mais pas mes journaux de fichiers. Après une tonne de fouilles, j'ai compris.
Veuillez noter que les packages tiers peuvent enregistrer des enregistreurs. C'est quelque chose à surveiller (et dans certains cas ne peut être évité). Dans de nombreux cas, le code tiers vérifie s'il existe une racine gestionnaires de journalisation ; et s'il n'y en a pas, ils enregistrent un nouveau gestionnaire de console.
Ma solution était d'enregistrer mon enregistreur de console au niveau racine:
la source