Doppelte Ausgabe in der einfachen Pythonprotokollierung

Ich setze die Pythonprotokollierung wie folgt ein:

def setup_logging(): loggers = (logging.getLogger("amcat"), logging.getLogger("scrapers"),logging.getLogger(__name__)) filename = "somefile.txt" sys.stderr = open(filename, 'a') handlers = (logging.StreamHandler(sys.stdout),logging.FileHandler(filename)) formatter = AmcatFormatter(date = True) for handler in handlers: handler.setLevel(logging.INFO) handler.setFormatter(formatter) for logger in loggers: logger.propagate = False logger.setLevel(logging.INFO) for handler in handlers: logger.addHandler(handler) logging.getLogger().handlers = [] 

2 Hauptmodul-Logger sind aktiviert, sie sollen sich sowohl an der Konsole als auch als Datei anmelden. Fehler werden in die Datei umgeleitet (idealerweise würden Fehler auch in der Konsole angezeigt, aber ich habe das noch nicht implementieren)

Gleich danach prüfe ich, ob es richtig ist:

 should_work = [ "amcat.scraping.scraper", "amcat.scraping.htmltools", "amcat.scraping.controller", "__main__"] loggerdict = logging.Logger.manager.loggerDict #all loggers for name, logger in loggerdict.items(): if name in should_work: print("\nlogger: "+name) #iterate through parents see if effective handlers are set correctly print(effectivehandlers(logger)) #test logger logger.info("test for {name}".format(**locals())) def effectivehandlers(logger): handlers = logger.handlers while True: logger = logger.parent handlers.extend(logger.handlers) if not (logger.parent and logger.propagate): break return handlers 

Die Konsolenausgabe:

 logger: __main__ [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for __main__ logger: amcat.scraping.controller [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller logger: amcat.scraping.htmltools [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools logger: amcat.scraping.scraper [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper 

Und hier ist die Datei ausgegeben:

 [2013-10-24 10:27:30 daily.py:133 INFO] test for __main__ [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper 

Wie Sie sehen können, ist die Ausgabe doppelt so hoch, obwohl sie die Ausbreitung deaktiviert hat und dass keine doppelten Handler vorhanden sind. Wo geht das falsch?

3 Solutions collect form web for “Doppelte Ausgabe in der einfachen Pythonprotokollierung”

Grundsätzlich, wenn einer deiner Kinderlogger eine Nachricht anzeigt, geht es rückwärts in die Hierarchie, und die Eltern protokollieren auch dasselbe.

Um dieses Verhalten abzubrechen, kannst du das hinzufügen:

 logger.propagate = False 

Wenn es auf das Kind trifft, wird es das Elternteil danach nicht treffen.

Hier ist eine Dokumentation über dieses Verhalten.

Ich habe das herausgefunden, danke Paco für mich in die richtige Richtung

Es stellt sich heraus, dass, wenn getLogger aufgerufen wird, Handler hinzugefügt werden:

 >>> print(effectivehandlers(logger)) [<logging.StreamHandler object at 0x305ad90>, <logging.FileHandler object at 0x305ae10>] >>> logging.getLogger(name) #the same logger <logging.Logger object at 0x7fa08fb9b2d0> >>> print(effectivehandlers(logger)) [<logging.StreamHandler object at 0x305ad90>, <logging.FileHandler object at 0x305ae10>, <logging.StreamHandler object at 0x305ad90>, <logging.FileHandler object at 0x305ae10>] 

Jetzt haben sowohl das Kind als auch das Elternteil die gleichen Handler. Daher doppelte Ausgänge.

Für python 2.7

 logging.handlers.pop() 

Referenz nach Benutzer "radtek": Python Logging – Meldungen erscheinen zweimal

  • Verwenden Sie die Protokollierung Python-Klasse, um eine Datei zu schreiben?
  • Python-Logger: wird das ursprüngliche Protokoll nicht überschreiben?
  • Python logging.info () protokolliert die Nachricht nicht
  • Python-Protokollierung, bevor Sie logging.basicConfig ausführen?
  • Protokollierung mit Filtern
  • Wie schreibt man benutzerdefinierte Python Logging Handler?
  • Sortiere Ausgabe in Python Logging MemoryHandler mit SMTPHandler
  • Python-Protokollierungsmodul-Protokollierungszeitstempel für Mikrosekunden
  • TimedRotatingFileHandler Ändern des Dateinamens?
  • Python multiprocessing logging: QueueHandler mit RotatingFileHandler "Datei wird von einem anderen Prozess" Fehler verwendet
  • Logger Kette in Python
  • Python ist die beste Programmiersprache der Welt.