Anleitungen

Logrotate für den Home-Server — Nützliche Logs, ohne die Festplatte zu füllen

Logrotate für den Home-Server — Nützliche Logs, ohne die Festplatte zu füllen

Logrotate für den Home-Server — Nützliche Logs, ohne die Festplatte zu füllen

Ein Home-Server kann monatelang unauffällig laufen, und genau deshalb geraten seine Logs leicht in Vergessenheit. Dann verweigert eines Abends eine Anwendung das Schreiben von Daten, ein Update schlägt fehl und df -h zeigt, dass eine scheinbar harmlose Logdatei den restlichen Speicherplatz belegt hat.

Ich betrachte Logs wie Kassenbelege in einer Küchenschublade. Sie aufzubewahren ist sinnvoll, wenn etwas geprüft werden muss, doch jeder Beleg für alle Zeiten macht die Schublade irgendwann unbrauchbar. logrotate gibt Linux eine Routine zum Aufräumen: das aktuelle Bündel abschließen, einen begrenzten Verlauf behalten, ältere Aufzeichnungen komprimieren und alles entfernen, dessen nützliche Lebensdauer abgelaufen ist.

Was Log Rotation tatsächlich bewirkt

Bei einer Rotation wird das aktive Log normalerweise nicht spurlos gelöscht. Die Datei wird umbenannt oder archiviert, Platz für eine neue Datei geschaffen und eine Retention Policy auf ältere Archive angewendet. Aus app.log kann app.log.1 und später app.log.2.gz werden, während die Anwendung in eine neue app.log weiterschreibt.

Damit werden zwei zusammenhängende Probleme gelöst. Erstens wächst eine einzelne Datei nicht mehr unbegrenzt. Zweitens bleibt Troubleshooting praktikabel, weil der jüngste Verlauf in vorhersehbaren Teilen erhalten bleibt. Rotation ist weder zentralisiertes Log Management noch ein Backup. Sie ist lokale Ordnung und bleibt wertvoll, unabhängig davon, ob der Server nur ein eigenes Skript oder einen vollständigen Observability Stack betreibt.

Die bestehende Einrichtung vor Änderungen prüfen

Unter Debian und vielen anderen Distributionen liegt die Hauptkonfiguration in /etc/logrotate.conf, während Package-spezifische Regeln unter /etc/logrotate.d/ gespeichert sind. Das System startet logrotate normalerweise über einen systemd timer oder einen geplanten Job. Prüfe zuerst die vorhandene Einrichtung, statt einen zweiten Scheduler anzulegen.

logrotate --version
systemctl status logrotate.timer
systemctl list-timers logrotate.timer
sudo ls -l /etc/logrotate.d/
sudo cat /etc/logrotate.conf

Der Timer kann täglich laufen, ohne dass jede Datei täglich rotiert wird. Der Scheduler fordert logrotate lediglich dazu auf, seine Regeln auszuwerten. Der in /var/lib/logrotate/status gespeicherte State hält fest, wann jedes Log zuletzt verarbeitet wurde. Diese Trennung ähnelt einem Hausmeister, der jeden Morgen alle Räume kontrolliert: Die Prüfung erfolgt täglich, aber ein Behälter wird nur geleert, wenn seine Regel dies vorsieht.

Eine Regel für eine eigene Anwendung erstellen

Angenommen, eine selbst gehostete Anwendung schreibt nach /var/log/myapp/app.log. Lege /etc/logrotate.d/myapp mit einer gezielten Policy an. Das folgende Beispiel rotiert wöchentlich, führt die Rotation aber früher aus, sobald die aktive Datei 50 MB erreicht.

/var/log/myapp/app.log {
    weekly
    size 50M
    rotate 8
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp adm
    su myapp adm
}

rotate 8 bewahrt acht archivierte Generationen auf. compress spart Speicherplatz, während delaycompress das neueste Archiv bis zum nächsten Zyklus unkomprimiert lässt. Das kann Software helfen, die die alte Datei kurzzeitig geöffnet hält. missingok verhindert einen Fehler bei einer fehlenden Logdatei, und notifempty überspringt eine leere Datei.

Die Zeile create bestimmt Berechtigungen, Eigentümer und Gruppe der Ersatzdatei. Diese Werte müssen zu dem Service passen, der das Log schreibt. Die Direktive su legt fest, mit welchem Benutzer und welcher Gruppe logrotate die Dateien in diesem Verzeichnis rotiert. Übernimm diese Identitäten nicht blind, sondern prüfe sie zunächst mit stat /var/log/myapp/app.log und in der Service Definition.

Zeit, Größe und Aufbewahrung bewusst wählen

Eine gute Policy orientiert sich an der erzeugten Datenmenge und an dem Verlauf, der wirklich nützlich ist. Für ein selten laufendes Backup-Skript kann eine monatliche Rotation genügen. Ein Reverse Proxy mit vielen Requests benötigt möglicherweise eine tägliche oder größenbasierte Rotation. Acht wöchentliche Archive ergeben ungefähr zwei Monate Verlauf, garantieren aber keine exakte Anzahl von Tagen, wenn der Size Threshold zusätzliche Rotationen auslöst.

Beachte den Unterschied zwischen size, minsize und maxsize. Mit size 50M wird die Größe zum primären Trigger. minsize 50M rotiert erst, wenn sowohl der geplante Zeitraum vergangen als auch die Datei groß genug ist. maxsize 50M erlaubt eine vorzeitige Rotation nach Überschreiten des Limits, selbst wenn das Zeitintervall noch nicht abgelaufen ist.

Die Aufbewahrung sollte außerdem den Recovery-Anforderungen entsprechen. Security und Audit Logs können einen längeren Zeitraum benötigen als umfangreiche Debug-Ausgaben. Eine Retention Rule ist jedoch keine vollständige Compliance Strategy. Wer den Server kompromittieren kann, kann möglicherweise auch lokale Archive verändern. Wichtige Nachweise sollten deshalb zusätzlich an ein getrenntes System mit geeigneten Access Controls übertragen werden.

Anwendungen mit geöffneten Dateien richtig behandeln

Das Umbenennen eines Logs funktioniert nur reibungslos, wenn die Anwendung ihre Datei erneut öffnen kann. Manche Daemons verstehen ein Signal, andere bieten einen Reload Command, und wieder andere schreiben weiter in die umbenannte Inode. Im letzten Fall bleibt die neue Datei leer, während der Speicherverbrauch im Archiv weiter steigt.

Füge für einen systemd service, der seine Logs nach einem Reload erneut öffnet, ein postrotate-Skript hinzu. Das Skript läuft nach der Rotation, und sharedscripts sorgt dafür, dass es nur einmal ausgeführt wird, auch wenn ein Pattern mehrere Dateien erfasst.

/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    missingok
    notifempty
    create 0640 myapp adm
    sharedscripts
    postrotate
        systemctl reload myapp.service >/dev/null 2>&1 || true
    endscript
}

Verwende den von der Anwendung empfohlenen Befehl, statt davon auszugehen, dass reload unterstützt wird. copytruncate ist eine Ausweichlösung, die eine Datei kopiert und das Original an Ort und Stelle leert. Im kurzen Zeitraum zwischen beiden Vorgängen können jedoch Schreibzugriffe verloren gehen. Die Methode ist bequem, aber nicht ideal. Anwendungen, die direkt in journald protokollieren, benötigen normalerweise keine eigene logrotate-Regel, da journald eigene Größen- und Aufbewahrungsgrenzen besitzt.

Die Regel testen, ohne Production Logs zu riskieren

Eine Konfiguration sollte getestet werden, bevor der nächste geplante Lauf ansteht. Der Debug Mode liest die Konfiguration ein und erklärt, was logrotate tun würde, ohne Dateien zu verändern. Führe ihn zuerst für die konkrete Regel aus.

sudo logrotate --debug /etc/logrotate.d/myapp
sudo logrotate --verbose /etc/logrotate.d/myapp

Der ausführliche Befehl führt nur Aktionen aus, die aktuell fällig sind. Für einen kontrollierten einmaligen Test lässt sich eine Rotation erzwingen. Dies sollte jedoch kein Routinebefehl werden, denn jeder Forced Run verschiebt die gesamte Archivkette.

sudo logrotate --force --verbose /etc/logrotate.d/myapp
sudo ls -lh /var/log/myapp/
sudo systemctl status myapp.service

Prüfe anschließend, ob der Service fehlerfrei läuft, die aktive Datei den erwarteten Eigentümer hat, neue Zeilen darin erscheinen und archivierte Dateien lesbar sind. Bei aktivierter Komprimierung können zless oder zgrep die .gz-Archive untersuchen, ohne sie manuell zu entpacken.

Die Policy überwachen, statt sie wieder zu vergessen

Rotation verringert das Risiko, doch ein Tippfehler, ein geändertes Service Account oder ein fehlgeschlagener Reload kann die Routine unbemerkt außer Kraft setzen. Prüfe den Timer bei der normalen Serverwartung und kontrolliere sein aktuelles Journal. Ein Disk Alert bleibt notwendig, denn Logs sind nur einer von mehreren möglichen Speicherverbrauchern.

systemctl list-timers logrotate.timer
journalctl -u logrotate.service --since "7 days ago"
df -h
sudo du -xhd1 /var/log | sort -h

Eine gesunde Policy liefert sichtbare Ergebnisse: begrenzte aktive Dateien, Archive mit plausiblen Datumsangaben, korrekte Berechtigungen und keine wiederkehrenden Fehler im Service Journal. Nach einer Änderung des Traffics sollten die Einstellungen erneut geprüft werden. Ein Limit von 50 MB, das für ein persönliches Projekt großzügig war, kann viel zu klein werden, sobald die Anwendung mehr Benutzer gewinnt.

Fazit: Logs begrenzen, statt sie wertlos zu machen

Das Ziel von logrotate besteht nicht darin, Logs verschwinden zu lassen. Sie sollen innerhalb einer für den Server tragbaren Grenze nützlich bleiben. Prüfe den vorhandenen Scheduler, schreibe eine eng gefasste Regel, stimme den Eigentümer auf die Anwendung ab, berücksichtige offene File Handles und teste im Debug Mode, bevor du etwas erzwingst.

Diese kleine Routine macht aus überraschendem Speicherverbrauch eine klare Policy. Wenn eine logrotate-Regel deinen Home-Server gerettet hat oder eine Anwendung einen ungewöhnlichen postrotate-Befehl benötigte, teile deine Erfahrung in den Kommentaren, damit andere Self-Hoster davon profitieren können.