Python-Protokollierung gibt nichts aus

Lesezeit: 8 Minuten

In einem Python-Skript, das ich schreibe, versuche ich, Ereignisse mit dem Protokollierungsmodul zu protokollieren. Ich habe den folgenden Code, um meinen Logger zu konfigurieren:

ERROR_FORMAT = "%(levelname)s at %(asctime)s in %(funcName)s in %(filename) at line %(lineno)d: %(message)s"
DEBUG_FORMAT = "%(lineno)d in %(filename)s at %(asctime)s: %(message)s"
LOG_CONFIG = {'version':1,
              'formatters':{'error':{'format':ERROR_FORMAT},
                            'debug':{'format':DEBUG_FORMAT}},
              'handlers':{'console':{'class':'logging.StreamHandler',
                                     'formatter':'debug',
                                     'level':logging.DEBUG},
                          'file':{'class':'logging.FileHandler',
                                  'filename':'/usr/local/logs/DatabaseUpdate.log',
                                  'formatter':'error',
                                  'level':logging.ERROR}},
              'root':{'handlers':('console', 'file')}}
logging.config.dictConfig(LOG_CONFIG)

Wenn ich versuche zu rennen logging.debug("Some string")bekomme ich aber keine Ausgabe an die Konsole diese Seite in den Dokumenten sagt, dass logging.debug sollte der Root-Logger die Meldung ausgeben. Warum gibt mein Programm nichts aus und wie kann ich das beheben?

Benutzeravatar von Hubert Grzeskowiak
Hubert Grzeskowiak

Viele Jahre später scheint es immer noch ein Usability-Problem mit dem Python-Logger zu geben. Hier einige Erklärungen mit Beispielen:

import logging
# This sets the root logger to write to stdout (your console).
# Your script/app needs to call this somewhere at least once.
logging.basicConfig()

# By default the root logger is set to WARNING and all loggers you define
# inherit that value. Here we set the root logger to NOTSET. This logging
# level is automatically inherited by all existing and new sub-loggers
# that do not set a less verbose level.
logging.root.setLevel(logging.NOTSET)

# The following line sets the root logger level as well.
# It's equivalent to both previous statements combined:
logging.basicConfig(level=logging.NOTSET)


# You can either share the `logger` object between all your files or the
# name handle (here `my-app`) and call `logging.getLogger` with it.
# The result is the same.
handle = "my-app"
logger1 = logging.getLogger(handle)
logger2 = logging.getLogger(handle)
# logger1 and logger2 point to the same object:
# (logger1 is logger2) == True

logger = logging.getLogger("my-app")
# Convenient methods in order of verbosity from highest to lowest
logger.debug("this will get printed")
logger.info("this will get printed")
logger.warning("this will get printed")
logger.error("this will get printed")
logger.critical("this will get printed")


# In large applications where you would like more control over the logging,
# create sub-loggers from your main application logger.
component_logger = logger.getChild("component-a")
component_logger.info("this will get printed with the prefix `my-app.component-a`")

# If you wish to control the logging levels, you can set the level anywhere 
# in the hierarchy:
#
# - root
#   - my-app
#     - component-a
#

# Example for development:
logger.setLevel(logging.DEBUG)

# If that prints too much, enable debug printing only for your component:
component_logger.setLevel(logging.DEBUG)


# For production you rather want:
logger.setLevel(logging.WARNING)

Eine häufige Ursache für Verwirrung ist ein schlecht initialisierter Root-Logger. Bedenken Sie:

import logging
log = logging.getLogger("myapp")
log.warning("woot")
logging.basicConfig()
log.warning("woot")

Ausgang:

woot
WARNING:myapp:woot

Abhängig von Ihrer Laufzeitumgebung und den Protokollierungsstufen Die erste Protokollzeile (vor der Grundkonfiguration) wird möglicherweise nirgendwo angezeigt.

  • Meine Protokollierung funktioniert nicht, da sie keine Ausgabedatei erzeugt. Sehen Sie irgendetwas, das ich tue, das eindeutig falsch ist?logging.basicConfig( filename='logging.txt', level=logging.DEBUG) logger = logging.getLogger() logger.info('Test B') logging.info('Test A')

    – Rylan Schäfer

    11. August 2020 um 15:39 Uhr


  • Die Protokolldatei wird nicht einmal erstellt

    – Rylan Schäfer

    11. August 2020 um 15:40 Uhr

  • Ich habe es bemerkt, als ich danach einen Haltepunkt ablegte logger = logging.getLogger()ist die Stufe auf WARNING gesetzt, obwohl ich die Stufe als angegeben habe DEBUG. Weißt du, was ich falsch mache?

    – Rylan Schäfer

    11. August 2020 um 15:44 Uhr

  • Hallo @RylanSchaeffer, vielleicht möchten Sie eine neue Frage erstellen und weitere Details angeben. Dies gibt auch anderen die Möglichkeit, Ihnen zu helfen.

    – Hubert Grzeskowiak

    12. August 2020 um 2:44 Uhr

  • Beachten Sie, dass wenn Sie Matplotlib verwenden und ausführen import matplotlib.pyplot as plt Nach dem Logging-Import, aber vor dem Rest des Codes (der auf pep8 folgen würde), bricht der Matplotlib-Import die Logging-Konfiguration ab und es werden keine Logging-Meldungen angezeigt.

    – Steven C. Howell

    27. Juli 2022 um 15:38 Uhr


Benutzeravatar von Omri Barel
Omri Barel

Die Standardprotokollierungsstufe ist Warnung. Da Sie die Ebene nicht geändert haben, ist die Ebene des Root-Loggers immer noch eine Warnung. Das bedeutet, dass jede Protokollierung mit einer niedrigeren Stufe als Warnung ignoriert wird, einschließlich Debug-Protokollierungen.

Dies wird in der erklärt Lernprogramm:

import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything

Die ‘info’-Zeile druckt nichts, weil das Level höher als info ist.

Um den Pegel zu ändern, stellen Sie ihn einfach im Root-Logger ein:

'root':{'handlers':('console', 'file'), 'level':'DEBUG'}

Mit anderen Worten, es reicht nicht aus, einen Handler mit level=DEBUG zu definieren, der eigentliche Logging-Level muss auch DEBUG sein, damit er etwas ausgibt.

  • Die Dokumentation sagt, dass die Standardebene NOTSET ist, was eine Ebene von 0 ist, die alles ausgeben sollte … Warum ist das nicht wahr?

    – Ben

    28. September 2017 um 23:03 Uhr

  • @Ben laut den Dokumenten werden die Logger durchquert, um den ersten Elternteil zu finden level != NOTSET oder die Wurzel (wenn keine gefunden wird). Die Wurzel hat WARNING Stufe standardmäßig. Dies steht in dem Abschnitt, auf den Sie verlinkt haben (Logger.setLevel).

    – Omri Barel

    3. Oktober 2017 um 16:32 Uhr

  • Denken Sie daran, dass nach dem Import logging du musst anrufen logging.basicConfig() mindestens einmal. Andernfalls könnten Sie sehr überrascht sein, dass untergeordnete Logger nichts drucken. Protokollierungsfunktionen auf dem Root-Logger nennen es faul.

    – Hubert Grzeskowiak

    28. August 2019 um 4:25 Uhr

  • Was meinst du damit, es im Root-Logger zu setzen 'root':{'handlers':('console', 'file'), 'level':'DEBUG'} ?

    – Ari

    2. Dezember 2019 um 21:56 Uhr

  • Dies ist nicht, was die Dokumentation (kein Lehrgang!) sagt! Die Dokumentation sagt, nur zB zu verwenden logging.basicConfig(level=logging.DEBUG). Dann logging.debug(...) gedruckt werden soll (Sie zeigen auch, was gedruckt wird). Also in meinem Fall auch nicht! Wie für 'root':{'handlers':('console', 'file'), 'level':'DEBUG'} … Wie und wo wird das verwendet??? Sie können so etwas nicht ohne ein Anwendungsbeispiel einwerfen! Ich frage mich wirklich, wie eine so schlechte und nutzlose Antwort so viele positive Stimmen bekommen hat! Es sollte stattdessen heruntergestimmt werden! (Habe ich nicht, weil ich das nicht mag.)

    – Apostolos

    8. Juli 2021 um 7:07 Uhr


Erics Benutzeravatar
erich

Für alle hier, die eine supereinfache Antwort wünschen: Stellen Sie einfach den Pegel ein, der angezeigt werden soll. An die Spitze aller meiner Skripte habe ich einfach gesetzt:

import logging
logging.basicConfig(level = logging.INFO)

Um dann etwas auf oder über dieser Ebene anzuzeigen:

logging.info("Hi you just set your fleeb to level plumbus")

Es handelt sich um einen hierarchischen Satz aus fünf Ebenen, sodass Protokolle auf der von Ihnen festgelegten Ebene angezeigt werden, oder höher. Wenn Sie also einen Fehler anzeigen möchten, können Sie verwenden logging.error("The plumbus is broken").

Die Ebenen sind in aufsteigender Reihenfolge nach Schweregrad DEBUG, INFO, WARNING, ERRORUnd CRITICAL. Die Standardeinstellung ist WARNING.

Dies ist ein guter Artikel, der diese Informationen enthält, die besser ausgedrückt sind als meine Antwort:
https://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3

  • Ausführungszeit mit hinzufügen logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s: %(message)s')

    – Jason

    16. Juni 2022 um 17:44 Uhr

  • Ich habe in einem separaten Skript eine einfache Funktion definiert, die beide oben genannten Aktionen ausführt (das Festlegen der Protokollierungsebene auf info und die Formatierung der Nachricht). Die Funktion wird dann direkt nach der Deklaration im Hauptskript verwendet id __name__ == "__main__". Aber das funktioniert nicht, Grundkonfigurationen sind nicht richtig eingestellt. Wo kann das Problem sein?

    – mattiatantardini

    12. September 2022 um 14:48 Uhr

Benutzeravatar von yue dong
du dong

Vielleicht versuchen Sie dies? Es scheint, dass das Problem gelöst ist, nachdem alle Handler in meinem Fall entfernt wurden.

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

logging.basicConfig(filename="output.log", level=logging.INFO)

Dieses Problem hat mich so viel Zeit verschwendet, also werde ich einfach etwas mehr investieren, um eine Antwort zu schreiben und Ihre zu retten

Problem

Die Protokollebene für benutzerdefinierte Logger kann nicht festgelegt werden. (z. B.: auf DEBUG-Ebene)

Was NICHT funktioniert

Festlegen der Protokollierungsebene für den Handler.

import logging

# Get logger
logger = logging.getLogger("my logger")

# Create a handler and set logging level for the handler
c_handler = logging.StreamHandler()
c_handler.setLevel(logging.DEBUG) # <- Here things went wrong

# link handler to logger
logger.addHandler(c_handler)

# test
logger.debug('This is a debug message') # WILL NOT WORK

LÖSUNG

Legen Sie das Logging-Level über das Logger-Objekt fest (anstelle des Handlers) Customlogger.setLevel(logging.DEBUG)

import logging

# Get logger
logger = logging.getLogger("my logger")

# Create a handler
c_handler = logging.StreamHandler()

# link handler to logger
logger.addHandler(c_handler)

# Set logging level to the logger
logger.setLevel(logging.DEBUG) # <-- THIS!

# test
logger.debug('This is a debug message') # WILL WORK

  • Hmm… was ist eigentlich mit unterschiedlichen Protokollebenen für Handler? Ich möchte, dass das Konsolenprotokoll INFO und das Dateiprotokoll DEBUG ist

    – JFCCorleone

    28. Oktober 2022 um 7:33 Uhr

  • Vielen Dank – das war … schmerzhaft.

    – Dante

    18. Januar um 10:17 Uhr

Cjos Benutzeravatar
Cjo

import logging
log = logging.getLogger()
log.setLevel(logging.DEBUG)

Dieser Code legt die Standardprotokollierungsebene auf DEBUG fest.

  • Hmm… was ist eigentlich mit unterschiedlichen Protokollebenen für Handler? Ich möchte, dass das Konsolenprotokoll INFO und das Dateiprotokoll DEBUG ist

    – JFCCorleone

    28. Oktober 2022 um 7:33 Uhr

  • Vielen Dank – das war … schmerzhaft.

    – Dante

    18. Januar um 10:17 Uhr

Benutzeravatar von Marwan Mostafa
Marwan Mostafa

Das funktioniert bei mir einfach…

import logging

LOGGER = logging.getLogger("my-fetcher")
logging.basicConfig(level=logging.INFO)

LOGGER.info("Established Connection Successfully!")
# > INFO:my-fetcher:Established Connection Successfully!

1443300cookie-checkPython-Protokollierung gibt nichts aus

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy