Die sogenannten Handler verwenden Sie, wenn Sie die Ausgabe in einen bestimmten Kanal lenken wollen. Mit einem »StreamHandler
«
schreibt ein Skript beispielsweise auf die Standardfehlerausgabe »sys.stderr
«
, wenn man keinen anderen Stream als Parameter übergibt:
console = logging.StreamHandler()
Ein »FileHandler
«
schreibt die Logging-Daten in eine Datei, mit einem »RotatingFileHandler
«
können Sie die Log-Dateien abhängig von Größe und Datum sogar rotieren lassen. Mit einem »SocketHandler
«
können Sie übers Netzwerk loggen, müssen allerdings einen großen Teil der Arbeit selbst übernehmen. Einfacher geht es mit dem »SysLogHandler
«
, der nicht nur Daten an den lokalen Syslog-Daemon schicken kann, sondern bei entsprechender Konfiguration auch an Syslogs auf anderen Rechnern (ab Python 2.7 auch mit TCP, siehe [4]). Für Windows-Anwender gibt es einen »NTEventLogHandler
«
, der die Daten an das Event-Log schickt. Selbst Logging per SMTP und HTTP ist möglich.
Wer einen langsamen Handler einsetzt, etwa einen SMTP-Logger, muss darauf achten, dass er damit nicht sein eigenes Programm blockiert. Ein Ausweg, den die Dokumentation vorschlägt, kann darin bestehen, einen Sockethandler zu verwenden, der die Logging-Daten an einen anderen Thread übergibt, der das eigentliche – und langsamere – Logging übernimmt. In Python 3.2 gibt es dafür eine neue Klasse namens »QueueHandler
«
. Einem existierenden Logger weisen Sie einen Handler folgendermaßen zu:
logging.getLogger('').addHandler(console)
Auf diese Weise ist es auch möglich, einem Logger mehrere Handler zuzuweisen, die sogar unterschiedliche Loglevel besitzen dürfen, und diese nach Wunsch beispielsweise auf die Console oder in ein Logfile schreiben zu lassen.
Wenn man unerwarteterweise eine Log-Meldung mehrfach präsentiert bekommt, sollte man daran denken, dass ein Logging-Event in der Hierarchiv der Logger bis nach oben durchgereicht und von jedem zuständigen Handler abgearbeitet wird. Um dieses Verhalten zu ändern, gibt es das Attribut »propagate
«
eines Handlers, das man dazu auf 0 setzt.
Alternativ zum Setup per Programm lassen sich Logger, Handler und so weiter auch über eine Konfigurationsdatei einrichten, das leider ein etwas umständliches Format verlangt: Zuerst sind die Schlüsselwörter (Keys) zu definieren, die weiter unten in der Konfigurationsdatei Verwendung finden, siehe Listing 2.
Listing 2
Konfigurationsdatei für Logger
Einfacher funktioniert das ab Python 2.7, das ein Dictionary-basiertes Format einführt, das diese umständlichen Referenzen überflüssig macht. Wie die Konfigurationsdaten ins Dictionary-Format kommen, bleibt dabei dem Anwender überlassen. Eine entsprechende Konfigurationsdatei kann beispielsweise in JSON, YAML oder anderen strukturierten Textformaten gespeichert sein. Ein Beispiel für eine Logger-Konfiguration in YAML ist in Listing 3 zu sehen.
Listing 3
Konfigurationsdatei ab Python 2.7
Das Logging-Modul von Python ist einfach zu benutzen und so flexibel, dass man ihm eigenen Skripts zur Ausgabe wichtiger Informationen gegenüber Print-Anweisungen den Vorzug geben sollte – wenn man nicht den Anwender gerade direkt informieren möchte. Zum Einstieg über diesen Artikel hinaus bieten sich ein Basic-, ein Fortgeschrittenen-Tutorial und das Logging Cookbook an, die in der Python-Dokumentation verlinkt sind. Aktuelle Informationen und Tipps rund um Python-Logging finden sich im Blog des Entwicklers [5].
Infos