Männer, die auf Logfiles starren

Eine häufige Tätigkeit im Leben eines Sysadmins ist das Analysieren von Logs. Je länger man diesen Job macht, desto ermüdender sind die üblichen ‘tail -f’s oder greps auf den Logfiles, auch wenn das Log eines produktiven Mailservers durchaus spannende Unterhaltung liefert.

Zur Routine gehört aber auch das Aufsuchen von bestimmten Mails oder die Identifikation eines Spammers. Hier hat der erfahrene Unix-Administrator normalerweise seine eigene Werkzeugkiste zur Hand, die meist aus einer Handvoll Perl-Skripte besteht. Obwohl mit Perl sicher elegante Programmierung möglich ist, sind doch die meisten solcher Skripte mal eben schnell zusammengehackt, was die Integration im Team mit anderen Admins erschwert.

Altlasten loswerden

Ich habe bereits vor langer Zeit aus verschiedenen Gründen von Perl auf Python umgeschwenkt. Auf der Suche nach passenden Werkzeugen zur Logfile-Analyse bin ich auf die elegante Bibliothek PyParsing gestossen. Die Installation bei vorhandener Python-Umgebung erfolgt einfach mit ‚‘python setup.py install’. Die Dokumentation ist hervorragend, allein daran können sich andere Programmierer schon mal eine Scheibe abschneiden.

Wer übrigens noch kein Python installiert hat, dem sei die freie Enthought-Distribution empfohlen, die auch viele Pakete zur grafischen Auswertung mitbringt.

Mit dem folgenden Code kann man ganz ohne kryptische reguläre Ausdrücke die Zeilen eines Syslogs in Variablen aufteilen und der Code bleibt lesbar!

from pyparsing import Word, alphas, Suppress, Combine, nums, string, Optional, Regex

month = Word(string.uppercase, string.lowercase, exact=3)
integer = Word(nums)
serverDateTime = Combine(month + " " + integer + " " + integer + ":" + integer + ":" + integer)
hostname = Word(alphas + nums + "_" + "-")
daemon = Word(alphas + "/" + "-" + "_") + Optional(Suppress("[") + integer + Suppress("]")) + Suppress(":")
message = Regex(".*")
bnf = serverDateTime + hostname + daemon + message

with open('/path/to/logfile') as syslogFile:
    for line in syslogFile:
        fields = bnf.parseString(line)
        print fields

Mit den übrigen Fähigkeiten von Python z.B. zum Datenbankzugriff lassen sich mächtige Auswertungswerkzeuge bauen und kontinuierlich erweitern. Nicht nur, dass ich auf dieses Werkzeug nicht mehr verzichten will: Diese Methode hat noch Erweiterungspotenzial für komplexere Analysen.