veröffentlicht am: 08.06.2020 zuletzt aktualisiert am: 02.02.2023
Viele Programmierer benutzen zur Fehlersuche die Funktion print. Oft werden die Funktionsaufrufe danach auskommentiert oder gelöscht. Stattdessen würde ich eher empfehlen, mit dem konfigurierbaren Python logging Modul zu arbeiten. Grund dafür ist, dass man dieses auch in produktiven Anwendungen beibehalten kann. Im Folgenden möchte ich dir zeigen, wie du das Modul logging zu diesem Zweck nutzen kannst.
Um logging zu nutzen, kannst du das Modul einfach importieren. Dieses stellt mehrere Funktionen bereit, die du nutzen kannst, um Meldungen auszugeben. Diese unterscheiden sich nach ihrem Level. Standardmäßig gibt es die Level debug, info, warning, error und critical.
import logging logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical')
WARNING:root:warning ERROR:root:error CRITICAL:root:critical
Anhand des vorigen Beispiels siehst du, dass nur die Nachrichten von warning, error und critical ausgegeben wurden. Das liegt daran, dass der Level in logging standardmäßig so konfiguriert ist, dass nur diese ausgegeben werden. Mit der Funktion basicConfig kannst du diesen anders konfigurieren:
logging.basicConfig(level=logging.DEBUG)
DEBUG:root:debug INFO:root:info WARNING:root:warning ERROR:root:error CRITICAL:root:critical
Zusätzlich kannst du an basicConfig noch den Parameter filename übergeben, welcher der Name der Datei ist, in der das Log gespeichert werden soll. Standardmäßig werden die Nachrichten sonst nur in der Textausgabe ausgegeben.
logging.basicConfig(filename='test.log', level=logging.DEBUG)
Wenn du dies nicht anders festlegst, wird die Logdatei bei jeder Ausführung des Programms erweitert. Dies wird durch den Dateimodus festgelegt, mit dem die Datei geöffnet wird. Diesen kannst du mit dem Parameter filemode beeinflussen. Der Wert w beispielsweise führt dazu, dass der vorige Inhalt überschrieben wird.
logging.basicConfig( filename='test.log', filemode='w', level=logging.DEBUG )
Wenn du mehr über filemode wissen willst, kannst du gerne unseren Artikel zu Python open lesen. Eine Übersicht über alle für filemode möglichen Werte findest du hier (https://docs.python.org/3/library/functions.html#open).
Weiterhin besteht die Möglichkeit, einen String anzugeben, der beeinflusst, was im Log angezeigt wird. Dafür können wir den Parameter format verwenden.
logging.basicConfig( filename='test.log', filemode='w', format='%(asctime)s %(levelname)s: %(message)s', level=logging.DEBUG )
2020-06-06 11:10:17,596 INFO: Hello world!
Weiterhin unterstützt basicConfig noch den Parameter datefmt. Mit diesem kannst du das Format in der Uhrzeit und Datum angezeigt werden festlegen.
logging.basicConfig( filename='test.log', filemode='w', format='%(asctime)s %(levelname)s: %(message)s', datefmt='%d.%m.%y %H:%M:%S', level=logging.DEBUG )
06.06.20 11:11:26 INFO: Hello world!
Für eine Übersicht über alle Optionen für datefmt empfiehlt sich dieser Abschnitt der Dokumentation (https://docs.python.org/3/library/time.html#time.strftime).
Du kannst logging in Klassen genauso verwenden wie im vorigen Abschnitt. Im Folgenden ist eine kleine Testklasse abgebildet, die eine Zahl durch eine andere teilt.
import logging logging.basicConfig(level=logging.DEBUG) class Test: def teilen(self, dividend, divisor): try: logging.info(f'teile {dividend} durch {divisor}') quotient = dividend / divisor logging.info(f'{dividend} / {divisor} = {quotient}') return quotient except Exception as e: logging.error(f'Fehler beim teilen ({dividend} / {divisor}):', exc_info=True) test = Test() e = test.teilen(1024, 128) e = test.teilen(1024, 0)
INFO:root:teile 1024 durch 128 INFO:root:1024 / 128 = 8.0 INFO:root:teile 1024 durch 0 ERROR:root:Fehler beim teilen (1024 / 0): Traceback (most recent call last): File ".\logging_python.py", line 35, in teilen quotient = dividend / divisor ZeroDivisionError: division by zero
Der Parameter exc_info von error hat im vorigen Beispiel dafür gesorgt, dass die Fehlermeldung auch im Log auftaucht.
Mit der Funktion getLogger kannst du einen Logger aufrufen oder erstellen. Meist wird für die Erstellung eines neuen Loggers die Variable __name__ verwendet. Diese enthält den Namen des Moduls, in dem sie verwendet wird.
logger = logging.getLogger(__name__)
Auch mit einem logger kannst du den Level bestimmen. Dafür verfügt die Klasse über die Methode setLevel.
logger.setLevel(logging.DEBUG)
Wir können den Logger genauso verwenden, wie logging zuvor. So würde unsere Klasse aus Abschnitt 2 mit dem Logger so aussehen:
class Test: def teilen(self, dividend, divisor): try: logger.info(f'teile {dividend} durch {divisor}') quotient = dividend / divisor logger.info(f'{dividend} / {divisor} = {quotient}') return quotient except Exception as e: logger.error(f'Fehler beim teilen ({dividend} / {divisor}):', exc_info=True)
Außerdem kannst du noch verschiedene Handler festlegen. Beispielsweise gibt es den sogenannten FileHandler, mit dem du festlegen kannst, in welcher Datei das Log gespeichert werden soll und mit welchem Modus es verwendet werden soll. Diesen Handlern kannst du sogenannte Formatter zuweisen, um das Verhalten von basicConfigs format- und datefmt-Parametern zu simulieren. Der FileHandler muss dann mittels der Methode addHandler zum Logger hinzugefügt werden.
formatter = logging.Formatter( '%(asctime)s %(levelname)s %(lineno)s: %(message)s', '%d.%m.%y %H:%M:%S' ) datei_handler = logging.FileHandler('file_handler.log', 'w') datei_handler.setFormatter(formatter) logger.addHandler(datei_handler)
INFO: teile 1024 durch 128 INFO: 1024 / 128 = 8.0
Natürlich kannst du deinem Logger mehrere Handler gleichzeitig zuweisen.
Pythons logging Modul stellt einige praktische Funktionen und Klassen zur Verfügung, um uns zu ermöglichen, Logs zu erstellen. Dies macht uns die Fehlersuche wesentlich einfacher. Wir können verschiedene Handler erstellen, um festzulegen wo das Log gespeichert bzw angezeigt werden soll. Jeder dieser Handler kann seine eigene Formatierung haben und ein Logger kann mehrere Handler gleichzeitig verwenden.
Wenn du noch Fragen, Anmerkungen, Lob oder Kritik hast, lass es mich bitte mit einem Kommentar wissen.
😩 Gelangweilt von den Udemy & YouTube-Tutorials?!
Lerne spielerisch Python und komme deiner gutbezahlten (und an der 🌴 liegenden) Traumkarriere einen Schritt weiter.
"Für Leute die gerne Python oder Java lernen wollen ist Codegree klasse. Ist nicht wie bei anderen Konkurrenten auf Videokursen aufgebaut..."
- Lennart Sparbier
100% kostenlos registrieren · keine Kreditkarte notwendig
Im Gegensatz zu der Abendschule oder der alteingesessenen Uni lernst du bei codegree die Sprachen & Pakete, die wirklich im Jobmarkt gesucht werden.
100% kostenlos registrieren · keine Zahlungsdaten notwendig