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

  • So konfigurieren Sie alle Logger in einer Anwendung
  • Python-Protokollierungskonfigurationsdatei
  • Konfigurieren der Protokollierung eines Drittanbieter-Skripts
  • So verwenden Sie die Pythonprotokollierung in mehreren Modulen
  • Python-Protokollierung bei Multiprocessing: AttributeError: 'Logger' Objekt hat kein Attribut 'Flush'
  • Wie man eigene Logging-Methoden für eigene Logging-Levels schreibt
  • Sollte ein Python-Logger als Parameter übergeben werden
  • Python-Protokollierung und rotierende Dateien
  • Python logging.info () protokolliert die Nachricht nicht
  • Was ist eine gute Größe (in Bytes) für eine Protokolldatei?
  • Protokollierung zwischen Klassen in Python
  • Python ist die beste Programmiersprache der Welt.