Direkt zum Inhalt

Loguru Python-Logging-Tutorial: Einrichtung ohne Konfiguration

Lerne Loguru, das einfachste Logging-Framework für Python. Meisterstdateirotation, strukturierte Protokollierung, Ausnahmebehandlung und benutzerdefinierte Senken ohne jegliche Konfiguration.
Aktualisierte 14. Aug. 2025  · 10 Min. Lesezeit

Du hast dein ganzes Programmierleben lang mit „ print() “-Anweisungen debuggt. Vielleicht hast du schon mal das Logging-Modul von Python ausprobiert, bist aber wieder zu Prints zurückgekehrt, weil die einfacher sind.

Es gibt sogar was Besseres, das genauso einfach zu benutzen ist.

Druckaufträge können nicht in Dateien gespeichert oder einfach so ein- und ausgeschaltet werden. Die integrierte Protokollierung von Python kann das, aber dafür musst du Setup-Code schreiben, der länger ist als dein eigentliches Programm.

Loguru macht es anders: Logging sollte so einfach sein wie Drucken, aber viel nützlicher. Du bekommst Farben in deinem Terminal, automatische Zeitstempel und kannst alles in Dateien speichern, ohne auch nur eine einzige Konfigurationszeile schreiben zu müssen.

In diesem Tutorial zeige ich dir praktische Beispiele, mit denen sich das Logging ganz natürlich anfühlt und nicht wie ne lästige Pflicht. Du wirst Funktionen entdecken, von denen du wahrscheinlich noch nichts wusstest, und Code-Muster kennenlernen, die das Debuggen echt einfacher machen.

Wenn du noch keine Erfahrung mit dem Debuggen in Python hast oder deine Grundkenntnisse vertiefen möchtest, sollten Sie sich solide Python-Grundkenntnisse aneignen hilft dir zu verstehen, wann und warum Logging notwendig ist.

Erste Schritte mit Loguru: Magie ohne Konfiguration

Loguru lässt sich mit einem einzigen Befehl installieren:

pip install loguru

Mit dem normalen Modul „ logging “ musst du Handler und Formatierer einrichten und alles konfigurieren, bevor du auch nur eine einzige Protokollmeldung siehst.

Für einen tiefergehenden Vergleich der integrierten Protokollierungsansätze von Python schau dir dieses umfassende Logging-Tutorial , das die traditionellen Methoden abdeckt.

Mit Loguru musst du nur importieren und kannst gleich loslegen:

from loguru import logger

# Instead of print("Processing user data...")
logger.info("Processing user data...")

# Instead of print(f"Found {count} records")
logger.info("Found {} records", count)

Die Ausgabe wird automatisch mit Farben, Zeitstempeln und Protokollstufen in deinem Terminal angezeigt. Keine Einrichtung nötig.

Loguru-Konsolenausgabe mit farbigen Protokollmeldungen mit Zeitstempeln und verschiedenen Protokollebenen im Python-Terminal

Nehmen wir mal an, du baust einen einfachen Web-Scraper. So ändert sich das Debugging:

import requests
from loguru import logger

def scrape_website(url):
   logger.info("Starting scrape for {}", url)
  
   response = requests.get(url)
   logger.debug("Response status: {}", response.status_code)
  
   if response.status_code == 200:
       logger.success("Successfully scraped {} characters", len(response.text))
       return response.text
   else:
       logger.error("Failed to scrape {}: status {}", url, response.status_code)
       return None

Achte auf die verschiedenen Protokollebenen (info, debug, success, error) und die Formatierung mit geschweiften Klammern. Alles funktioniert sofort, ohne dass du irgendwelche Konfigurationsdateien oder Setup-Code brauchst.

Dateiprotokollierung und -rotation leicht gemacht

Wenn du mit der Konsolenausgabe debuggt, geht alles verloren, sobald du dein Terminal schließt. Du kannst nicht nach Dingen suchen, die vor einer Stunde passiert sind, und wenn dein Skript über Nacht abstürzt, gibt's keine Ahnung, was schiefgelaufen ist. Außerdem kannst du deine Debugging-Ergebnisse nicht einfach mit deinen Teamkollegen teilen, wenn du um Hilfe bittest.

Die Dateiprotokollierung löst das, indem sie alles dauerhaft speichert.

Beim normalen Logging musst du Konfigurationscode schreiben, um Datei-Handler einzurichten. Du musst Dateipfade angeben, Verzeichnisse erstellen und Berechtigungen verwalten. Mit Loguru ist das Hinzufügen der Dateiprotokollierung buchstäblich eine Zeile:

from loguru import logger

# Add file logging alongside console output
logger.add("app.log")

logger.info("This appears in both console and file")
logger.error("So does this error message")

Jetzt wird alles unter app.log gespeichert und trotzdem noch in deinem Terminal angezeigt.

Aber Log-Dateien werden mit der Zeit echt riesig. Eine Web-App, die tagelang läuft, kann Gigabytes an Logs produzieren, die irgendwann deine Festplatte vollmachen. Die Dateirotation löst das, indem automatisch neue Logdateien erstellt werden, wenn bestimmte Bedingungen erfüllt sind. Die alte Datei wird mit einem Zeitstempel umbenannt und eine neue Datei wird erstellt:

# When app.log reaches 10 MB, it becomes app_2024-07-15_14-30-25.log
# and a new empty app.log starts
logger.add("app.log", rotation="10 MB")

# Or start a new file every day at midnight
logger.add("app.log", rotation="00:00")

Die Standard-Zeitstempel funktionieren, sind aber oft in UTC oder schwer zu lesen. Mit Loguru kannst du Datums- und Zeitformate nach deinen Bedürfnissen anpassen:

# Custom timestamp format that's easier to read
logger.add("app.log",
         format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}",
         rotation="1 day")

Für Produktionssysteme brauchst du mehr Kontrolle über alte Dateien. Für die Produktionsprotokollierung musst du die Python-Best Practices befolgen, damit deine Protokolle pflegbar und sicher sind. Ohne Verwaltung stapeln sich Log-Dateien und belegen Speicherplatz:

# Keep only the last 10 rotated files, compress the rest
logger.add("production.log",
         rotation="50 MB",     # New file every 50MB
         retention=10,         # Keep only 10 old files
         compression="zip")    # Compress rotated files

Schauen wir uns das mal in einem echten Szenario an. Du baust eine Datenpipeline auf, die jede Nacht mehrere CSV-Dateien verarbeitet, Kundendaten bereinigt und validiert, bevor sie in deine Datenbank geladen werden. Du musst einen Lernpfad erstellen, um zu verfolgen, welche Dateien erfolgreich verarbeitet wurden, und etwaige Probleme mit der Datenqualität zu erkennen:

import pandas as pd
from loguru import logger

# Production-ready file logging setup
logger.add("data_processing_{time:YYYY-MM-DD}.log",
         rotation="00:00",        # New file daily
         retention="1 week",      # Keep 1 week of logs
         format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}")

def process_csv_files(file_list):
   logger.info("Starting batch processing of {} files", len(file_list))
  
   for filename in file_list:
       try:
           df = pd.read_csv(filename)
           logger.info("Loaded {} with {} rows", filename, len(df))
          
           # Your processing logic here
           processed_df = df.dropna()
          
           logger.success("Processed {} - kept {} rows", filename, len(processed_df))
          
       except Exception as e:
           logger.error("Failed to process {}: {}", filename, str(e))
  
   logger.info("Batch processing complete")

Deine Logs werden mit lesbaren Zeitstempeln gespeichert, Dateien werden automatisch rotiert und alte Logs werden automatisch gelöscht. Du kannst später checken, was passiert ist, oder Log-Dateien an Kollegen schicken, wenn du Probleme beheben musst.

Strukturierte Protokollierung für moderne Apps

Wenn du eine Web-App betreibst, werden deine Logs schnell zu einem Durcheinander aus verschiedenen Infos. Benutzeraktionen, Datenbankabfragen, API-Aufrufe und Fehler werden alle in einer Textwand zusammengefasst. Du kannst nicht einfach nach bestimmten Benutzern filtern, einzelne Anfragen verfolgen oder Protokolle automatisch für Überwachungssysteme analysieren.

Datenbasierte Anwendungen profitieren besonders von strukturierter Protokollierung. Wenn du mit Datenpipelines oder Analysen arbeitest, helfen dir Datenanalyse-Kenntnisse dabei, zu verstehen, welche Infos du in deinen Protokollen erfassen solltest.

Die klassische Protokollierung mit Strings macht das Ganze noch schlimmer. Jede Protokollmeldung ist nur Text, sodass du für die Extraktion aussagekräftiger Daten komplexe reguläre Ausdrücke oder manuelle Suchvorgänge brauchst.

Strukturierte Protokollierung ändert das, indem sie Protokolleinträge als Datenobjekte und nicht nur als Text behandelt. Jeder Protokolleintrag wird zu einem strukturierten Datensatz mit durchsuchbaren Feldern, sodass er einfach programmgesteuert abgefragt und analysiert werden kann.

JSON-strukturierte Protokollierung mit serialize=True

Loguru macht strukturiertes Logging mit der Option „ serialize=True ganz einfach:

from loguru import logger

# Enable JSON structured logging
logger.add("api.log", serialize=True)

logger.info("User login", user_id=123, ip_address="192.168.1.1")
logger.error("Payment failed", user_id=123, amount=99.99, error_code="INSUFFICIENT_FUNDS")

Der Parameter „ serialize=True “ sagt Loguru, dass es JSON statt reinem Text ausgeben soll. Statt lesbaren Sätzen hat deine Logdatei jetzt strukturierte Daten:

{"text": "User login", "record": {"time": "2024-07-15T14:30:25", "level": {"name": "INFO"}, "extra": {"user_id": 123, "ip_address": "192.168.1.1"}}}

Dieses Format passt super zu Tools für die Log-Analyse, die JSON-Daten automatisch durchsuchen und filtern können.

Kontextbindung

Aber Web-Apps brauchen mehr als nur strukturierte Daten. Du brauchst einen Zusammenhang, der ähnliche Log-Einträge verbindet. Wenn du eine Benutzeranfrage bearbeitest, solltest du sicherstellen, dass alle zugehörigen Protokolle gemeinsame Infos wie die Benutzer-ID oder die Sitzungs-ID haben.

Kontextbindung löst das, indem sie mit logger.bind() dauerhafte Infos an deinen Logger hängt:

from loguru import logger

def process_user_order(user_id, order_data):
   # Create a logger with attached context
   order_logger = logger.bind(user_id=user_id, order_id=order_data['id'])
  
   order_logger.info("Starting order processing")
   order_logger.debug("Validating payment method", method=order_data['payment'])
   order_logger.info("Order processing complete", total=order_data['total'])

Jetzt enthält jeder Log von order_logger automatisch user_id und order_id, sodass alle Logs zu einer bestimmten Bestellung ganz einfach nachverfolgt werden können.

Mehrere Senken für verschiedene Ausgänge

Moderne Anwendungen brauchen auch unterschiedliche Protokollausgaben für verschiedene Zwecke. Während der Entwicklung möchtest du vielleicht lesbare Konsolenprotokolle, für die Produktionsüberwachung aber JSON-Protokolle. In Loguru wird jedes Ausgabeziel als „Sink“ bezeichnet – stell dir das als einen Ort vor, an den Log-Meldungen fließen.

Mit Loguru kannst du mehrere Sinks mit unterschiedlichen Formaten und Regeln hinzufügen:

from loguru import logger
import sys

# Remove the default console output
logger.remove()

# Sink 1: Human-readable console for development
logger.add(sys.stdout,
         level="DEBUG",
         format="<green>{time:HH:mm:ss}</green> | {level} | {message}")

# Sink 2: JSON file for production monitoring
logger.add("app.log",
         serialize=True,
         level="INFO")

# Sink 3: Error-only file for alerts
logger.add("errors.log",
         level="ERROR")

Der Aufruf „ logger.remove() “ löscht die Standard-Konsolenausgabe von Loguru, damit du deine eigene einrichten kannst. Jeder logger.add() ” macht eine neue „Sink” mit eigenen Regeln, was protokolliert wird und wie das aussieht.

Jetzt liefern dieselben Protokollanweisungen unterschiedliche Ausgaben:

logger.debug("Processing started")      # Only appears in console
logger.info("User data loaded")         # Appears in console and app.log
logger.error("Database connection failed")  # Appears in all three places

Komplettes Loguru-Beispiel: Benutzerregistrierung

Schauen wir uns das mal an einem einfacheren, realistischeren Beispiel für die Verwendung von Loguru an – einem einfachen Benutzerregistrierungssystem:

from loguru import logger
import sys

# Set up multiple outputs
logger.remove()
logger.add(sys.stdout, level="INFO", format="{time:HH:mm:ss} | {message}")
logger.add("user_registration.log", serialize=True, level="INFO")
logger.add("errors.log", level="ERROR")

def register_user(email, password):
   # Create logger with user context
   user_logger = logger.bind(email=email)
  
   user_logger.info("Starting user registration")
  
   # Validate email
   if "@" not in email:
       user_logger.error("Invalid email format")
       return False
  
   # Check if user exists
   user_logger.debug("Checking if user already exists")
  
   # Simulate password hashing
   user_logger.debug("Hashing password")
  
   # Save to database
   user_logger.info("Saving user to database")
   user_logger.success("User registration completed")
  
   return True

# Usage
register_user("john@example.com", "secure123")

Mit dieser Konfiguration bekommst du während der Entwicklung eine übersichtliche Konsolenausgabe, strukturierte JSON-Protokolle für die automatisierte Überwachung und separate Fehlerprotokolle für Warnmeldungen. Die Methode „ bind() “ sorgt dafür, dass alle Protokolle für jede Benutzerregistrierung die E-Mail-Adresse enthalten, was die Fehlersuche echt vereinfacht.

Loguru-Ausnahmebehandlung

Wenn dein Code abstürzt, bekommst du normalerweise einen einfachen Stacktrace, der dir sagt, wo der Fehler aufgetreten ist, aber nicht viel darüber, warum. Du verlierst die Werte der Variablen zum Zeitpunkt des Absturzes, was es schwierig macht, zu verstehen, was schiefgelaufen ist. Bei der herkömmlichen Ausnahmebehandlung musst du auch alles in try-catch-Blöcke packen und jede Ausnahme manuell protokollieren.

Das ist besonders nervig, wenn man Probleme in der Produktion debuggt. Benutzer melden Fehler, aber du kannst sie nicht nachmachen, weil du nicht den Kontext kennst, in dem der Fehler aufgetreten ist.

Loguru löst das mit automatischer Ausnahmeerfassung und verbesserten Rückverfolgungen, die dir genau zeigen, was in deinem Code passiert ist, als etwas schiefgelaufen ist.

Automatisches Erfassen von Ausnahmen mit @logger.catch

Der Dekorator „ @logger.catch ” fängt automatisch alle Ausnahmen ab, die in einer Funktion auftreten, und protokolliert sie mit dem vollständigen Kontext. Dekoratoren wie @logger.catch “ sind ein Zwischenkonzept in Python, das die Art und Weise, wie du Fehler in deinem Code behandelst, grundlegend verändern kann:

from loguru import logger

@logger.catch
def divide_numbers(a, b):
   result = a / b
   return result

# This automatically logs the exception with full traceback
result = divide_numbers(10, 0)

Anstatt dass dein Programm mit einer einfachen Fehlermeldung abstürzt, fängt Loguru die Ausnahme ab und protokolliert sie mit detaillierten Infos, während dein Programm weiterläuft. Der Dekorator funktioniert bei jeder Funktion – Klassenmethoden, asynchrone Funktionen oder normale Funktionen.

Verbesserte Rückverfolgung mit Variablenprüfung

Aber Loguru geht noch weiter und zeigt mit verbesserten Tracebacks die Werte der Variablen auf jeder Ebene des Aufrufstapels an. Diese Funktion heißt „Diagnose“ und ist wie ein Debugger, der in deine Protokolle eingebaut ist:

from loguru import logger

# Enable enhanced tracebacks
logger.add("debug.log", diagnose=True)

@logger.catch
def process_user_data(users):
   for user in users:
       age = user['age']
       if age > 0:
           years_to_retirement = 65 - age
           print(f"User {user['name']} has {years_to_retirement} years to retirement")

# When this crashes, you'll see the exact values of 'users', 'user', and 'age'
users_data = [
   {"name": "Alice", "age": 30},
   {"name": "Bob", "age": "invalid"},  # This will cause an error
]

process_user_data(users_data)

Mit diagnose=True “ zeigt Loguru dir genau, was in jeder Variablen war, wenn die Funktion beim Versuch, eine Zeichenfolge von einer Zahl zu subtrahieren, abstürzt:

TypeError: unsupported operand type(s) for -: 'int' and 'str'

Variables values:
   users = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": "invalid"}]
   user = {"name": "Bob", "age": "invalid"}
   age = "invalid"

Dank dieser Detailgenauigkeit geht das Debuggen viel schneller, weil du genau siehst, welche Daten das Problem verursacht haben.

Umgebungsbewusste Ausnahmebehandlung

Allerdings können erweiterte Tracebacks sensible Infos wie Passwörter oder API-Schlüssel in Produktionsprotokollen offenlegen. Mit Loguru kannst du dieses Verhalten für verschiedene Umgebungen steuern:

from loguru import logger
import os

# Development: Full diagnostic information
if os.getenv("ENVIRONMENT") == "development":
   logger.add("app.log", diagnose=True, level="DEBUG")
else:
   # Production: Basic logging without variable inspection
   logger.add("app.log", diagnose=False, level="INFO")

@logger.catch
def authenticate_user(username, password, api_key):
   # In development, you'll see all variable values if this crashes
   # In production, sensitive data stays hidden
   if not username or not password:
       raise ValueError("Missing credentials")

Lazy Evaluation für mehr Performance

Eine weitere coole Funktion ist die verzögerte Auswertung, die die Leistung bei der Protokollierung von aufwendigen Vorgängen verbessert. Manchmal willst du komplexe Infos protokollieren, aber nur, wenn tatsächlich ein Fehler auftritt:

from loguru import logger

@logger.catch
def process_large_dataset(data):
   try:
       # Some complex processing that might fail
       result = complex_calculation(data)
       return result
   except Exception as e:
       # This expensive operation only runs if there's an error
       logger.error("Processing failed with data: {data}",
                   data=lambda: expensive_data_summary(data))
       raise

def expensive_data_summary(data):
   # This function takes time to run, summarizing huge datasets
   return {"row_count": len(data), "columns": list(data.keys()), "memory_usage": data.memory_usage()}

Die Syntax „ lambda: “ macht eine Funktion, die nur dann aufgerufen wird, wenn Loguru die Log-Nachricht tatsächlich schreibt. Wenn kein Fehler auftritt, wird „ expensive_data_summary() “ nie ausgeführt, was Rechenzeit spart.

Unterschiedliche Strategien für verschiedene Fehlerarten

Du kannst auch verschiedene Strategien zum Umgang mit Ausnahmen für verschiedene Arten von Fehlern verwenden:

from loguru import logger

# Configure multiple outputs for different error severities
logger.add("warnings.log", level="WARNING", filter=lambda record: record["level"].name == "WARNING")
logger.add("critical_errors.log", level="ERROR")

@logger.catch(level="ERROR")
def critical_database_operation(query):
   # Database errors get logged as ERROR level
   execute_database_query(query)

@logger.catch(level="WARNING", reraise=False)
def optional_feature(user_id):
   # Non-critical features log as WARNING and continue execution
   send_optional_notification(user_id)

def process_user_request(user_id, query):
   # Critical operation - if this fails, the whole request fails
   critical_database_operation(query)
  
   # Optional operation - if this fails, request continues
   optional_feature(user_id)

Der Parameter „ reraise=False “ sagt Loguru, dass die Ausnahme protokolliert, aber nicht erneut ausgelöst werden soll, sodass dein Programm weiterlaufen kann. Das ist praktisch für optionale Funktionen, die deinen Haupt-Workflow nicht stören sollen.

Komplettes Beispiel: Dateiverarbeitung mit Fehlerbehandlung

Schauen wir uns mal ein komplettes Beispiel mit einem Dateiverarbeitungssystem an, das verschiedene Arten von Fehlern elegant abfängt:

from loguru import logger
import os

# Set up environment-aware logging
if os.getenv("DEBUG"):
   logger.add("file_processor.log", diagnose=True, level="DEBUG")
else:
   logger.add("file_processor.log", diagnose=False, level="INFO")

@logger.catch(reraise=False)
def validate_file_format(filename):
   if not filename.endswith(('.csv', '.json', '.xml')):
       raise ValueError(f"Unsupported file format: {filename}")

@logger.catch
def load_file_data(filename):
   logger.info("Loading file: {}", filename)
  
   # Expensive operation only logged on errors
   logger.debug("File stats: {stats}",
               stats=lambda: {"size": os.path.getsize(filename),
                             "modified": os.path.getmtime(filename)})
  
   with open(filename, 'r') as f:
       return f.read()

def process_files(file_list):
   results = []
  
   for filename in file_list:
       # Validation errors are logged but don't stop processing
       validate_file_format(filename)
      
       try:
           # Loading errors are logged and do stop processing this file
           data = load_file_data(filename)
           results.append(data)
           logger.success("Successfully processed {}", filename)
       except Exception:
           logger.error("Skipping file {} due to loading error", filename)
           continue
  
   return results

Mit dieser Konfiguration bekommst du automatisch Ausnahmen erfasst, bei Bedarf detaillierte Fehlerkontexte und verschiedene Strategien, um mit unterschiedlichen Fehlern umzugehen. Deine Protokolle werden viel nützlicher für die Fehlersuche, während dein Code übersichtlich und lesbar bleibt.

Erweiterte Loguru-Konfiguration und Anpassung

Wenn deine Anwendungen wachsen, wirst du Situationen haben, in denen die Standardeinstellungen von Loguru nicht ganz passen. Vielleicht brauchst du einen speziellen Protokollierungsgrad für Geschäftsmetriken, möchtest sensible Daten aus den Protokollen herausfiltern oder bei Fehlern Benachrichtigungen an Slack senden.

Das coole daran ist, dass Loguru so gemacht ist, dass man es anpassen kann, ohne dass es kompliziert wird. Du kannst es auf eine Art erweitern, die bei herkömmlichen Protokollierungssystemen eine komplizierte Konfiguration erfordern würde, und dabei deinen Code übersichtlich und lesbar halten.

Schauen wir uns mal die nützlichsten Anpassungen an, die echte Probleme lösen, auf die du in Produktionsanwendungen stoßen wirst.

Benutzerdefinierte Protokollstufen und Farben

Loguru kommt mit Standardstufen wie INFO, DEBUG und ERROR. Aber manchmal brauchst du etwas, das speziell auf deine Anwendung zugeschnitten ist. Vielleicht brauchst du eine spezielle Ebene für Leistungskennzahlen oder Geschäftsereignisse.

Benutzerdefinierte Protokollstufen zu erstellen ist ganz einfach:

from loguru import logger

# Add a custom level for business metrics
logger.level("METRIC", no=38, color="<yellow>", icon="📊")

# Add a custom level for security events
logger.level("SECURITY", no=45, color="<red><bold>", icon="🔒")

# Now you can use these levels
logger.log("METRIC", "Order completed in {} seconds", 2.5)
logger.log("SECURITY", "Failed login attempt from IP: {}", "192.168.1.100")

Der Parameter „ no “ legt die Priorität der Ebene fest (höhere Zahlen = höhere Priorität). Standard-Niveaustufen: DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50.

Schauen wir uns das mal in einem Machine-Learning-Trainingsszenario an:

from loguru import logger

# Set up custom levels for ML tracking
logger.level("EPOCH", no=35, color="<cyan><bold>")
logger.level("CHECKPOINT", no=38, color="<green><bold>")

# Configure output
logger.remove()
logger.add("training_{time:YYYY-MM-DD}.log", level="INFO")

def train_model(model, data_loader, epochs=10):
   logger.info("Starting training with {} epochs", epochs)
  
   for epoch in range(epochs):
       # Log epoch progress with custom level
       logger.log("EPOCH", "Epoch {}/{} started", epoch + 1, epochs)
      
       # Training logic here
       loss = 0.523 - (epoch * 0.05)  # Simulated improving loss
       accuracy = 0.72 + (epoch * 0.03)  # Simulated improving accuracy
      
       logger.info("Loss: {:.4f}, Accuracy: {:.2%}", loss, accuracy)
      
       # Save checkpoint every 5 epochs
       if (epoch + 1) % 5 == 0:
           logger.log("CHECKPOINT", "Model saved at epoch {}", epoch + 1)
  
   logger.success("Training completed!")

Protokollmeldungen abfangen und ändern

Manchmal musst du Log-Meldungen ändern, bevor sie geschrieben werden. Häufige Anwendungsfälle sind das Löschen sensibler Daten, das Hinzufügen von Anforderungs-IDs oder das Umformatieren von Nachrichten für bestimmte Tools.

Mit Loguru kannst du Nachrichten über den Parameter „ filter abfangen:

from loguru import logger
import re

def hide_sensitive_data(record):
   # Hide credit card numbers
   record["message"] = re.sub(r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b',
                             'XXXX-XXXX-XXXX-XXXX',
                             record["message"])
  
   # Hide email addresses
   record["message"] = re.sub(r'\b[\w.-]+@[\w.-]+\.\w+\b',
                             '***@***.***',
                             record["message"])
  
   # Continue processing the log
   return True

# Add the filter to your logger
logger.add("secure.log", filter=hide_sensitive_data)

# Test it
logger.info("User paid with card 4532-1234-5678-9012")
logger.info("Contact email: john.doe@example.com")

Du kannst auch Filter verwenden, um Kontextinfos hinzuzufügen:

from loguru import logger
import threading

def add_thread_info(record):
   # Add thread name to every log message
   record["extra"]["thread_name"] = threading.current_thread().name
   return True

def add_environment_info(record):
   # Add environment to production logs
   record["extra"]["env"] = "production"
   record["extra"]["region"] = "us-west-2"
   return True

# Apply multiple filters
logger.add(
   "app.log",
   filter=lambda record: add_thread_info(record) and add_environment_info(record),
   format="{time} | {extra[env]} | {extra[thread_name]} | {message}"
)

Maßgefertigte Waschbecken für Außenbereiche

Ein Sink ist der Ort, an den deine Protokolle fließen. Dateien und Konsolen sind zwar weit verbreitet, aber oft musst du Logs an externe Dienste wie Slack, E-Mail oder Überwachungssysteme senden.

So kannst du einen benutzerdefinierten Sink erstellen, der Fehler an Slack sendet:

from loguru import logger
import requests

def send_to_slack(message):
   """Custom sink that sends messages to Slack"""
   # Parse the log record
   record = message.record
  
   # Only send errors and above
   if record["level"].no < 40:  # ERROR level is 40
       return
  
   # Format message for Slack
   slack_message = {
       "text": f"🚨 {record['level'].name}: {record['message']}",
       "attachments": [{
           "color": "danger",
           "fields": [
               {"title": "Time", "value": str(record["time"]), "short": True},
               {"title": "Function", "value": record["function"], "short": True},
               {"title": "File", "value": f"{record['file'].name}:{record['line']}", "short": False}
           ]
       }]
   }
  
   # Send to Slack webhook
   webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
   requests.post(webhook_url, json=slack_message)

# Add the custom sink
logger.add(send_to_slack, level="ERROR")

# Test it
logger.error("Database connection lost!")

Hier ist ein weiteres praktisches Beispiel: ein benutzerdefinierter Sink, der während der gesamten Ausführung Ihrer Anwendung Leistungsmetriken erfasst und zur Analyse speichert:

from loguru import logger
from collections import defaultdict
import json

class MetricsCollector:
   def __init__(self):
       self.metrics = defaultdict(list)
  
   def __call__(self, message):
       """This method is called for every log message"""
       record = message.record
      
       # Only process METRIC level logs
       if record["level"].name != "METRIC":
           return
      
       # Extract metric data from the 'extra' fields
       extra = record["extra"]
       if "metric_name" in extra and "value" in extra:
           self.metrics[extra["metric_name"]].append({
               "value": extra["value"],
               "timestamp": record["time"].timestamp()
           })
  
   def save_metrics(self):
       """Save all collected metrics to a JSON file"""
       with open("metrics.json", "w") as f:
           json.dump(dict(self.metrics), f, indent=2)

# Create the collector and add it as a sink
collector = MetricsCollector()
logger.add(collector)

# Create the METRIC level
logger.level("METRIC", no=38)

# Now when you log metrics, they're automatically collected
# The bind() method attaches extra data to the log entry
logger.bind(metric_name="response_time", value=0.234).log("METRIC", "API response")
logger.bind(metric_name="response_time", value=0.189).log("METRIC", "API response")
logger.bind(metric_name="active_users", value=1523).log("METRIC", "User count")

# Later, save all metrics to file
collector.save_metrics()

# The metrics.json file will contain:
# {
#   "response_time": [
#     {"value": 0.234, "timestamp": 1627...},
#     {"value": 0.189, "timestamp": 1627...}
#   ],
#   "active_users": [
#     {"value": 1523, "timestamp": 1627...}
#   ]
# }

Das coole an diesem Ansatz ist, dass dein Anwendungscode übersichtlich bleibt – du protokollierst einfach wie gewohnt die Metriken und der Collector Sink kümmert sich automatisch um die Speicherung. Du kannst das ganz einfach gegen ein Sink austauschen, das Metriken an Prometheus, DataDog oder einen anderen Überwachungsdienst sendet.

Mit diesen Anpassungen kannst du Loguru ganz einfach an deine Bedürfnisse anpassen, ohne dass es dabei seine tolle Einfachheit verliert. Egal, ob du ein kleines Skript oder eine große Anwendung entwickelst, du kannst Loguru erweitern, um deine individuellen Protokollierungsanforderungen ohne komplizierte Konfigurationsdateien oder Boilerplate-Code zu erfüllen.

Fazit

Loguru macht das Logging in Python so einfach, wie es sein sollte. Keine Konfigurationsdateien mehr, kein Handler-Setup mehr, kein Boilerplate-Code mehr. Einfach importieren und loslegen – mit Farben, Zeitstempeln und automatischer Dateirotation.

Du hast gesehen, wie es mit den üblichen Problemen klärt: Protokolle in Dateien speichern, automatisch rotieren, Ausnahmen mit vollem Kontext erfassen und Protokolle an externe Dienste senden. Die strukturierten Protokollierungsfunktionen machen es einsatzbereit, während du es mit benutzerdefinierten Ebenen und Senken an jeden Anwendungsfall anpassen kannst.

Verwende Loguru, wenn:

  • Du hast keine Lust mehr auf das Debuggen von Ausdrucken
  • Du brauchst schnell Skripte oder Notizbücher zum Einloggen?
  • Du entwickelst Webanwendungen, die strukturierte Protokolle brauchen.
  • Du willst eine bessere Ausnahmeverfolgung ohne komplizierte Einrichtung

Wenn du mehr wissen willst, schau dir neben diesem Logging-Tutorial auch die offizielle Dokumentation an, wo du alles über Python-Logging-Strategien erfährst.

Fang klein an. Ersetz eine print-Anweisung durch „ logger.info() “. Du wirst nie wieder zurück wollen.

Loguru – Häufig gestellte Fragen

Wie schneidet Loguru im Vergleich zu anderen Python-Logging-Bibliotheken ab?

Loguru ist super, weil du nichts einrichten musst – du kannst sofort loslegen mit „from loguru import logger“. Anders als das integrierte Logging-Modul von Python, das Handler, Formatierer und eine komplexe Einrichtung braucht, bietet Loguru Farben, Zeitstempel und Dateirotation direkt aus der Box. Außerdem gibt's verbesserte Rückverfolgungen mit variabler Überprüfung, die andere Bibliotheken nicht bieten.

Was sind die Hauptvorteile von Loguru gegenüber dem integrierten Logging-Modul von Python?

Loguru macht Schluss mit komplizierten Konfigurationen, sorgt für automatische Dateirotation und -aufbewahrung, bietet strukturierte JSON-Protokollierung mit serialize=True, hat verbesserte Ausnahme-Tracebacks mit Variablenwerten und unterstützt benutzerdefinierte Sinks für externe Dienste. Du bekommst sofort einsatzbereite Logging-Funktionen, ohne irgendwelchen Setup-Code schreiben zu müssen.

Kann Loguru Anwendungen mit mehreren Threads gut verarbeiten?

Ja, Loguru ist standardmäßig threadsicher und kommt gut mit Anwendungen mit mehreren Threads klar. Du kannst Thread-Infos mit Filtern zu Logs hinzufügen, und die Methode logger.bind() funktioniert threadübergreifend, um den Kontext beizubehalten. Die Leistung von Loguru ist so optimiert, dass mehrere Protokollierungen gleichzeitig laufen können, ohne Threads zu blockieren.

Wie funktioniert die automatische Log-Rotation und -Aufbewahrung von Loguru?

Loguru bietet flexible Rotation basierend auf Dateigröße (Rotation=&quot;10 MB&quot;), Zeitintervallen (Rotation=&quot;00:00&quot; für täglich) oder benutzerdefinierten Bedingungen. Die Aufbewahrungsfunktion löscht automatisch alte Dateien (Aufbewahrung=10 behält 10 Dateien) und die Komprimierung spart Speicherplatz (Komprimierung=&quot;zip&quot;). Alles läuft automatisch, ohne dass du Dateien manuell verwalten musst.

Was sind praktische Beispiele für die Verwendung der benutzerdefinierten Sink-Funktionen von Loguru?

Mit benutzerdefinierten Sinks kannst du Protokolle an externe Dienste wie Slack für Fehlermeldungen senden, Metriken für Überwachungssysteme sammeln oder Protokolle für bestimmte Tools formatieren. Du kannst Sinks erstellen, die nach Protokollstufe filtern, Kontextinfos hinzufügen oder mit Diensten wie DataDog, Prometheus oder E-Mail-Benachrichtigungen für kritische Fehler integrieren.


Bex Tuychiev's photo
Author
Bex Tuychiev
LinkedIn

Ich bin ein Data Science Content Creator mit über 2 Jahren Erfahrung und einem der größten Follower auf Medium. Ich schreibe gerne ausführliche Artikel über KI und ML mit einem etwas sarkastischen Stil, denn man muss etwas tun, damit sie nicht so langweilig sind. Ich habe mehr als 130 Artikel verfasst und einen DataCamp-Kurs gemacht, ein weiterer ist in Vorbereitung. Meine Inhalte wurden von über 5 Millionen Augenpaaren gesehen, von denen 20.000 zu Followern auf Medium und LinkedIn wurden. 

Themen

Top-Kurse von DataCamp

Lernpfad

Python Daten Grundlagen

0 Min.
Erweitere deine Datenkenntnisse, entdecke, wie du Daten manipulieren und visualisieren kannst, und wende fortgeschrittene Analysen an, um datengestützte Entscheidungen zu treffen.
Siehe DetailsRight Arrow
Kurs starten
Mehr anzeigenRight Arrow