Logging in Python: Vom print() zum strukturierten Log
print() ist zum Debuggen praktisch – aber ab einer gewissen Projektgröße wird es unübersichtlich. Das logging-Modul aus der Standardbibliothek bringt Ordnung: Log-Level, Formatierung und getrennte Ausgaben.
Fast jedes Python-Skript beginnt mit dem gleichen Reflex: Etwas funktioniert nicht wie erwartet, also streuen wir schnell ein paar print()-Aufrufe ein, um zu sehen, was passiert. Für einen kleinen Test ist das völlig in Ordnung. Doch sobald ein Projekt wächst – mehrere Module, ein Hintergrundprozess, vielleicht ein Server, der tagelang läuft – zeigt print() seine Grenzen. Genau hier lohnt sich der Umstieg auf das logging-Modul aus der Standardbibliothek.
Warum print() irgendwann nicht mehr reicht
Das Problem an print() ist nicht, dass es nicht funktioniert, sondern dass es keine Struktur kennt. Jede Ausgabe ist gleich wichtig, es gibt keine Unterscheidung zwischen einer harmlosen Info und einem schweren Fehler. Willst du die Ausgaben später abschalten, musst du jede einzelne Zeile suchen und löschen. Und alles landet im selben Ausgabestrom, unabhängig davon, ob es sich um eine Debug-Meldung oder eine kritische Warnung handelt.
Ein echtes Logging-System löst all diese Punkte. Es kennt Log-Level, es lässt sich zentral konfigurieren, und es kann dieselbe Meldung gleichzeitig auf die Konsole und in eine Datei schreiben – ohne dass du deinen eigentlichen Code anfassen musst.
Die fünf Log-Level
Der Kern von logging sind fünf Stufen, die den Schweregrad einer Meldung ausdrücken: DEBUG, INFO, WARNING, ERROR und CRITICAL. Du entscheidest pro Nachricht, welche Stufe passt – und legst separat fest, ab welchem Level überhaupt etwas ausgegeben wird.
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.debug("Detail, nur beim Debuggen interessant")
logger.info("Programm gestartet")
logger.warning("Konfigurationsdatei fehlt, nutze Standardwerte")
logger.error("Verbindung zur Datenbank fehlgeschlagen")Steht der Level auf INFO, wird die debug-Zeile stillschweigend übersprungen. Willst du im Fehlerfall mehr sehen, setzt du den Level an einer einzigen Stelle auf DEBUG – und plötzlich erscheinen alle Details, ganz ohne den Code umzuschreiben.
Formatierung: Zeitstempel und Kontext automatisch
Ein weiterer Vorteil: Logging kann jede Zeile automatisch mit nützlichem Kontext anreichern – Zeitstempel, Modulname, Level. Das macht Logs deutlich leichter auswertbar, gerade wenn ein Problem erst Stunden später auffällt.
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)Statt einer nackten Textzeile bekommst du nun so etwas wie 2026-08-14 09:12:03 [WARNING] app.config: Konfigurationsdatei fehlt. Wer schon einmal ein Produktivsystem debuggen musste, weiß, wie viel Zeit solche Zeitstempel sparen.
Der entscheidende Denkschritt
Der wichtigste Perspektivwechsel ist dieser: Mit print() bestimmt der Code, was ausgegeben wird. Mit logging trennst du das Erzeugen einer Meldung vom Ausgeben. Dein Code sagt nur „das hier ist eine Warnung" – und eine zentrale Konfiguration entscheidet, ob und wohin sie geschrieben wird. Diese Trennung ist der Grund, warum professionelle Projekte praktisch nie print() für Diagnosezwecke verwenden.
Wenn du tiefer einsteigen und auch Handler, mehrere Ausgabeziele und typische Stolperfallen verstehen willst, gibt es dazu einen sehr gründlichen englischsprachigen Deep-Dive auf unserer Schwesterseite pykit.org: Stop Reaching for print(): A Practical Deep Dive into Python's logging Module. Dort wird Schritt für Schritt gezeigt, wie du Logs sauber in Dateien umleitest und Logger über Module hinweg strukturierst.
Fazit
Für ein Wegwerf-Skript bleibt print() völlig legitim. Aber sobald dein Programm länger lebt als ein einzelner Testlauf, ist der Umstieg auf logging eine der lohnendsten kleinen Investitionen, die du machen kannst. Log-Level geben dir Kontrolle darüber, was du siehst, die Formatierung liefert Kontext gratis, und die zentrale Konfiguration hält deinen eigentlichen Code sauber. Fang klein an: Ersetze in deinem nächsten Projekt jedes print() durch den passenden logger-Aufruf – und du wirst den Unterschied schon beim ersten echten Fehler spüren.