Cronwrapper Logs mehrerer Server zentral sammeln
Es ist gar nicht so lange her, dass ich 20 Jahre Cronwrapper vermeldet habe [1].
Der Cronwrapper vereinfacht die Handhabe, Logging und Überwachung von Cronjobs [2]. OK, er ist von mir geschrieben, aber ich mag irgendwie, was er wie tut - schon dass man Ausgabe schreiben kann, wie man will, sich nicht um Ausgabe-Umlenkung und Loggin kümmern muss. Die Asugabe ist normiert, dass man mit grep
schnell zu Details, wie Laufzeit oder Exitcode kommt. Ein mitgeliefertes cronstatus.sh liefert basierend darauf pfannenfertig den Zustand aller lokal laufenden Cronjobs. Aber wer will sich denn dafür auf jeden Server einloggen? Ich hätte da lieber eine zentrale Cronjob-Zentrale.
Wir haben an unserem Institut 200+ Server. Die meisten haben einen Cronjob … oder mehrere. Bisher hatte ich einen Hilfs-Cronjob am Laufen, der alle 5 min ein rsync zu einem Logserver machte. Aber alle paar Minuten immer wieder nur dumm rsync starten, ist auch nicht gerade so toll.
Daher wurde das Sync-Skript [3] erweitert: er startet nur dann rsync, wenn tatsächlich ein neueres Logfile nach dem letzten Sync vorliegt. Das ist selten einfach zu implementieren: nach dem Rsync toucht man eine Datei im Logverzeichnis. Beim nächsten Aufruf ein ls -ltr
und man schaut, ob die neueste Datei noch immer das Touchfile ist. Das würde die Zahl der rsyncs deutlich reduzieren, wenn es nur stündlich oder tägliche Cronjobs gibt.
Was ist noch besser? Nur dann synchen, wenn tatsächlich ein Cronjob gelaufen ist. Der Pferdefus ist: ich habe Jobs mit unsterschiedlichen Usern am Laufen. Ein Skript des Cronjobs unter einem x-beliebigen User laufend kann nicht selbst zum Abschluss das rsync auslösen.
Aber ich habe schonmal für ähnlichgelagerte Zwecke ein Skript onfilechange geschrieben [4], das bei Modifikation eines Fileobjekts ein Kommando startet. Initial entstand es, damit Vorgänge mit unprivilegierten Benutzer (mit SSH Zugang oder auch anderweitig) auf einem Applikationsserver den Webservice restarten zu können, was eben nur als root geht. Das Skript selbst loopt zwar ewig, aber man kann es recht einfach in ein Systemd Configfile verpacken, damit es als Systemd Prozess handhabbar ist [5]. Also: man kann es per systemctl
starten/ stoppen oder mit jounrnalctl -u [Name]
im Systemlog dessen Aktionen begutachten.
Für unsere Logs des Cronwrappers läuft ebenjenes onfilechange Skript in einem solechen systemd Service mit dem User, der berechtigt ist, zu einem Logserver per SSH zu verbinden. Es überwacht das Logverzeichnis des Cronwrappers und startet bei Änderung das Sync-Skript.
Zielserver und Zielverzeichnis liegen in einer Configdatei, die sich mit Ansible, Puppet und Co einfach generieren lässt.
Es gibt pro Server ein eigenes Zielverzeichnis - es enthält dabei den FQDN des jeweiligen Systems.
Last but not least: Auf einem Logserver ein grosses Logverzeichnis vieler Server … wie ist nun das zu handhaben? Dazu ist vor ein paar Jahren auch ein Webinterface mit PHP entstanden, das über alle Server und Jobs durch deren Logs browsen lässt: der Cronlog Viewer [6].
weiterführende Links: