
- Fehler mit
logrotate -dreproduzieren und die genaue Zeile identifizieren. - Konfiguration auf Klammerung, Semikolon und
endscriptprüfen. - Skript isoliert mit
bash -xtesten und Rückgabewert auswerten. - Berechtigungen, SELinux- und AppArmor-Kontexte korrigieren.
- Mit erzwungenem Lauf verifizieren und Überwachung einrichten.
Was ist ein postrotate-Skript in Logrotate und welche Rolle spielt es?
Ein postrotate-Skript wird von Logrotate nach dem Rotieren einer Logdatei ausgeführt, um den schreibenden Dienst zum erneuten Öffnen seines Dateideskriptors zu bewegen. Ohne diesen Schritt schreibt der Dienst weiter in die bereits umbenannte Datei, und die neue Logdatei bleibt leer. Das ist kein theoretisches Problem: In meiner Praxis als Systemarchitekt habe ich auf über 200 Servern gesehen, dass fehlerhafte postrotate-Skripte zu monatelang fehlenden Logs führen, ohne dass es jemandem auffällt. Die Rotation selbst funktioniert, aber die Anwendung verliert ihre Logs — ein gefährlicher Zustand, besonders bei der Fehlerbehebung.
Kurz gesagt :
- Fehler mit logrotate -d reproduzieren und die genaue Zeile identifizieren.
- Konfiguration auf Klammerung, Semikolon und endscript prüfen.
- Skript isoliert mit bash -x testen und Rückgabewert auswerten.
- Berechtigungen, SELinux- und AppArmor-Kontexte korrigieren.
Die Funktionsweise von Logrotate auf einem Linux-Server
Logrotate ist ein Werkzeug der Systemverwaltung, das von einem cron-Job oder einem systemd-Timer periodisch aufgerufen wird. Es liest seine Konfiguration aus /etc/logrotate.conf und den Fragmenten in /etc/logrotate.d/. Für jede Logdatei entscheidet es anhand von Kriterien wie Größe oder Alter, ob rotiert wird. Der Ablauf ist deterministisch: umbenennen, komprimieren, aufräumen, dann die Skripte ausführen. Diese Reihenfolge ist wichtig, denn postrotate läuft erst, wenn die alte Datei bereits verschoben wurde.
Der Unterschied zwischen prerotate, postrotate und firstaction
Logrotate kennt mehrere Skript-Hooks, die zu unterschiedlichen Zeitpunkten greifen. prerotate läuft vor der Rotation, postrotate danach, und firstaction sowie lastaction umrahmen den gesamten Zyklus über alle Logdateien hinweg. Verwechselt man diese Hooks, entstehen schwer nachvollziehbare Fehler. Ein postrotate-Skript, das eigentlich vor der Rotation laufen müsste, findet die Datei nicht mehr vor und scheitert still.
Warum ein fehlerhaftes postrotate-Skript den gesamten Rotationszyklus blockiert
Ein nicht abgefangener Fehler im postrotate-Skript führt dazu, dass Logrotate einen Exit-Code ungleich null zurückgibt. Bei nachfolgenden Logdateien im selben Block wird die Rotation dann übersprungen. Das ist ein Performance-Engpass, der sich kumuliert: Die Logs wachsen unkontrolliert, bis die Partition vollläuft. Ich habe erlebt, dass ein einzelnes fehlendes Semikolon dazu führte, dass ein Webserver nach zwei Wochen keine Logs mehr schrieb und die Festplatte zu 100 % gefüllt war.
Warum treten Fehler in postrotate-Skripten so häufig auf?
Die meisten Fehler entstehen durch die Diskrepanz zwischen der interaktiven Shell, in der das Skript getestet wurde, und der minimalistischen Umgebung, in der Logrotate es ausführt. Diese Umgebung hat einen reduzierten PATH, keine interaktiven Aliase und oft ein anderes Arbeitsverzeichnis. Wer das nicht berücksichtigt, schreibt Skripte, die manuell funktionieren, im Cron-Kontext aber scheitern.
Typische Ursachen: fehlende Berechtigungen, falsche Pfade und nicht vorhandene Binärdateien
In meinen Audits tauchen immer wieder dieselben drei Ursachen auf. Fehlende Berechtigungen, weil das Skript als root läuft, aber eine Datei einem anderen Benutzer gehört. Falsche Pfade, weil relative Angaben wie ./reload.sh im Logrotate-Kontext nicht aufgelöst werden. Und nicht vorhandene Binärdateien, weil systemctl im eingeschränkten PATH nicht gefunden wird. All diese Fehler sind vermeidbar, wenn man die Umgebung explizit setzt.
Das Problem mit der Shell-Umgebung und dem eingeschränkten PATH
Logrotate ruft Skripte mit /bin/sh auf, nicht mit Ihrer interaktiven Bash. Auf Debian und Ubuntu ist /bin/sh oft ein Symlink auf dash, was bedeutet, dass Bash-spezifische Konstrukte wie [[ ]] oder function fehlschlagen. Der PATH ist typischerweise auf /usr/bin:/bin beschränkt. Ich empfehle daher, in jedem postrotate-Skript absolute Pfade zu verwenden und die Shell explizit anzugeben, etwa mit #!/bin/bash als erste Zeile.
Fehlinterpretation der sharedscripts-Direktive
Die sharedscripts-Direktive bestimmt, ob ein Skript einmal für alle Logdateien im Block oder für jede Datei einzeln ausgeführt wird. Ohne sharedscripts läuft postrotate für jede Datei separat. Das kann bei Diensten, die nur ein Signal benötigen, zu mehrfachen Reloads führen und unnötige Last erzeugen. Mit sharedscripts läuft das Skript genau einmal, was in den meisten Fällen die richtige Wahl ist. Ich habe Fälle gesehen, in denen ein fehlendes sharedscripts dazu führte, dass ein Datenbankdienst 20-mal pro Rotation neu geladen wurde.
1. Den genauen Fehler mit dem Logrotate-Debug-Modus reproduzieren
Der Debug-Modus ist Ihr wichtigstes Werkzeug, weil er den gesamten Ablauf simuliert, ohne Dateien zu verändern. Mit logrotate -d /etc/logrotate.d/mein-dienst sehen Sie jede Entscheidung und jeden ausgeführten Befehl. Achten Sie auf Zeilen, die mit error: oder failed beginnen. In meiner Erfahrung deckt dieser Schritt bereits 70 % der Fehler auf, weil er die tatsächliche Ausführungsumgebung zeigt.
Logrotate im Testlauf mit -d ausführen
Führen Sie den Debug-Lauf immer mit der vollständigen Konfigurationsdatei aus, nicht nur mit einem Ausschnitt. Der Befehl logrotate -d /etc/logrotate.conf zeigt Ihnen die kumulierte Wirkung aller Fragmente. Prüfen Sie besonders die Zeilen, in denen running postrotate script steht. Wenn dort ein Fehler folgt, haben Sie die Ursache eingegrenzt.
Die Ausgabe des Fehlercodes in /var/lib/logrotate/status prüfen
Logrotate speichert den Status jeder Rotation in /var/lib/logrotate/status. Ein Exit-Code ungleich null im Skript wird dort nicht immer sichtbar, aber die Zeitstempel zeigen, ob eine Rotation übersprungen wurde. Vergleichen Sie die Zeitstempel mit dem erwarteten Intervall. Wenn eine Datei seit mehreren Tagen nicht rotiert wurde, obwohl die Konfiguration täglich greift, liegt ein blockierender Fehler vor.
Den Systemd-Timer und den Cron-Job unter die Lupe nehmen
Auf modernen Distributionen wird Logrotate meist von logrotate.timer ausgelöst, nicht von einem klassischen cron-Job. Prüfen Sie mit systemctl list-timers | grep logrotate, ob der Timer aktiv ist. Ein deaktivierter Timer ist eine häufige Ursache für ausbleibende Rotationen. Auf älteren Systemen finden Sie den Eintrag in /etc/cron.daily/logrotate.
2. Die Konfigurationsdatei des betroffenen Dienstes analysieren
Die Konfigurationsdatei unter /etc/logrotate.d/ ist die Quelle der Wahrheit. Isolieren Sie den postrotate-Block und prüfen Sie ihn Zeile für Zeile. Die Syntax von Logrotate ist eigenwillig: Das Skript muss mit endscript abgeschlossen werden, und davor steht oft ein Semikolon. Fehlt eines von beiden, scheitert die gesamte Datei.
Die Datei unter /etc/logrotate.d/ öffnen und den postrotate-Block isolieren
Öffnen Sie die Datei mit einem Editor, der Zeilennummern anzeigt. Suchen Sie nach postrotate und markieren Sie alles bis endscript. Kopieren Sie diesen Block in eine separate Datei, um ihn isoliert zu testen. So vermeiden Sie, dass andere Direktiven Ihre Analyse verfälschen.
Die Klammerung und das Semikolon am Ende des Skripts kontrollieren
Ein häufiger Fehler ist ein fehlendes Semikolon nach dem letzten Befehl. Logrotate erwartet, dass jeder Befehl im Skriptblock mit einem Semikolon oder einem Zeilenumbruch endet. Besonders bei einzeiligen Skripten wie postrotate /usr/bin/systemctl reload nginx > /dev/null; endscript ist das Semikolon vor endscript entscheidend. Ohne es interpretiert Logrotate den Befehl falsch.
Die endscript-Direktive auf korrekte Schreibweise überprüfen
endscript muss kleingeschrieben und ohne Leerzeichen davor stehen. Ich habe Fälle gesehen, in denen end script oder EndScript verwendet wurde — beides führt zu einem Syntaxfehler, der die gesamte Datei ungültig macht. Logrotate meldet dann error: unexpected end of file, was die Fehlersuche unnötig erschwert.
3. Das Skript manuell in einer isolierten Shell testen
Der manuelle Test in einer isolierten Shell ist der schnellste Weg, um Umgebungsprobleme auszuschließen. Kopieren Sie den Skriptinhalt in eine temporäre Datei und führen Sie ihn mit bash -x aus. Die Option -x zeigt jeden ausgeführten Befehl und deckt fehlende Variablen oder falsche Pfade auf.
Den Skriptinhalt in eine temporäre Datei kopieren und mit bash -x ausführen
Erstellen Sie die Datei /tmp/test_postrotate.sh und fügen Sie den Inhalt zwischen postrotate und endscript ein. Führen Sie sie mit bash -x /tmp/test_postrotate.sh aus. Achten Sie auf Zeilen, die mit + beginnen und auf einen Fehler folgen. So sehen Sie genau, welcher Befehl scheitert.
Die Umgebungsvariablen von Logrotate mit env -i nachstellen
Um die minimale Umgebung nachzustellen, führen Sie das Skript mit env -i /bin/bash /tmp/test_postrotate.sh aus. Damit verlieren Sie alle Umgebungsvariablen außer denen, die Sie explizit setzen. Wenn das Skript hier scheitert, aber interaktiv funktioniert, liegt es an fehlenden Variablen wie PATH oder HOME.
Den Rückgabewert mit echo $? auswerten
Nach der Ausführung gibt echo $? den Exit-Code des letzten Befehls zurück. Ein Wert ungleich null bedeutet, dass Logrotate die Rotation als fehlgeschlagen markiert. In meiner Praxis ist der Exit-Code 1 der häufigste, gefolgt von 127 (Befehl nicht gefunden). Beide sind eindeutige Hinweise auf die Ursache.
4. Berechtigungen, Besitzer und SELinux-Kontexte korrigieren
Auf gehärteten Systemen sind Berechtigungsfehler die häufigste Ursache für scheiternde postrotate-Skripte. Logrotate läuft als root, aber die Zielverzeichnisse und Dateien können anderen Benutzern gehören. SELinux und AppArmor fügen eine zusätzliche Ebene hinzu, die oft übersehen wird.
Die Ausführung als root und die Rechte der Zielverzeichnisse prüfen
Prüfen Sie mit ls -la die Rechte der Verzeichnisse, in die das Skript schreibt. Ein Skript, das als root läuft, kann in die meisten Verzeichnisse schreiben, aber nicht in solche, die mit chattr +i unveränderlich gemacht wurden. Auch NFS-Mounts mit root_squash können Probleme verursachen.
SELinux mit ausearch und audit2allow auf Verweigerungen untersuchen
Auf RHEL und CentOS prüfen Sie mit ausearch -m avc -ts recent, ob SELinux Zugriffe verweigert hat. Die Ausgabe zeigt Ihnen den Kontext und die Aktion. Mit audit2allow -a -M meinmodul erzeugen Sie eine Richtlinie, die die Verweigerung behebt. Ich rate jedoch dazu, die Ursache zu verstehen, bevor Sie eine pauschale Erlaubnis erteilen.
AppArmor-Profile unter Debian und Ubuntu anpassen
Auf Debian und Ubuntu ist AppArmor die Standard-Mandatory-Access-Control. Prüfen Sie mit dmesg | grep apparmor auf Verweigerungen. Die Profile liegen unter /etc/apparmor.d/. Wenn ein Profil den Zugriff auf eine Binärdatei oder ein Verzeichnis blockiert, müssen Sie es anpassen oder in den Beschwerdemodus versetzen.
5. Das postrotate-Skript robust neu schreiben
Ein robustes postrotate-Skript ist defensiv geschrieben und behandelt Fehler explizit. Es verwendet absolute Pfade, prüft Rückgabewerte und sendet Signale auf die richtige Weise. In meiner Architekturarbeit hat sich ein Muster bewährt, das ich Ihnen hier vorstelle.
Absolute Pfade statt relativer Angaben verwenden
Verwenden Sie immer /usr/bin/systemctl statt systemctl. Der PATH im Logrotate-Kontext ist unzuverlässig. Auch für Konfigurationsdateien und Logverzeichnisse sollten Sie absolute Pfade angeben. Das eliminiert eine ganze Klasse von Fehlern.
Fehlerbehandlung mit set -e und expliziten Exit-Codes einbauen
Mit set -e bricht das Skript beim ersten Fehler ab. Das ist oft gewünscht, aber nicht immer. Bei optionalen Befehlen hängen Sie || true an, um den Fehler zu ignorieren. Setzen Sie am Ende ein explizites exit 0, um einen sauberen Abschluss zu signalisieren. So vermeiden Sie, dass ein unwichtiger Fehler die gesamte Rotation blockiert.
Signale an den Dienst korrekt senden, zum Beispiel mit systemctl reload
Der Zweck des postrotate-Skripts ist es, den Dienst zum erneuten Öffnen seiner Logdateien zu bewegen. Bei systemd-Diensten ist systemctl reload der richtige Weg, sofern der Dienst dies unterstützt. Andernfalls senden Sie SIGUSR1 mit kill -USR1 $(cat /run/mein-dienst.pid). Prüfen Sie die Dokumentation Ihres Dienstes, um das richtige Signal zu wählen.
6. Die Korrektur verifizieren und dauerhaft absichern
Nach der Korrektur müssen Sie sicherstellen, dass die Rotation dauerhaft funktioniert. Ein einzelner erfolgreicher Lauf reicht nicht. Richten Sie eine Überwachung ein, die ausbleibende Rotationen erkennt, bevor sie zum Problem werden.
Einen erzwungenen Rotationslauf mit logrotate -f starten
Mit logrotate -f /etc/logrotate.d/mein-dienst erzwingen Sie eine Rotation, unabhängig von den Kriterien. Prüfen Sie anschließend, ob die neue Logdatei angelegt wurde und der Dienst weiterhin schreibt. Ein Blick in die Logdatei des Dienstes zeigt, ob das erneute Öffnen funktioniert hat.
Die Logs von journalctl und /var/log/syslog auf Restfehler prüfen
Prüfen Sie journalctl -u logrotate und /var/log/syslog auf Fehlermeldungen. Ein erfolgreicher Lauf hinterlässt keine Spuren, ein fehlgeschlagener schon. Achten Sie auf Wiederholungen: Ein Fehler, der einmal auftritt, ist ein Ausrutscher, einer, der sich wiederholt, ist ein Systemproblem.
Eine Überwachung mit logwatch oder einem Monitoring-Werkzeug einrichten
Richten Sie eine Überwachung ein, die die Größe der Logdateien und das Alter der letzten Rotation prüft. Werkzeuge wie logwatch oder Prometheus mit dem node_exporter können dies leisten. Ich empfehle eine Warnung, wenn eine Logdatei älter als das Doppelte des Rotationsintervalls ist. Das gibt Ihnen Zeit zu reagieren, bevor die Partition vollläuft.
Checkliste: Die häufigsten Fehler in postrotate-Skripten vermeiden
Diese Checkliste fasst die Fehler zusammen, die ich in meinen Audits am häufigsten gesehen habe. Gehen Sie sie durch, bevor Sie ein postrotate-Skript in Produktion nehmen.
- Fehlende Leerzeichen oder Zeilenumbrüche zwischen den Direktiven und dem Skriptblock.
- Verwendung von relativen Pfaden, die im Logrotate-Kontext nicht aufgelöst werden.
- Vergessenes Semikolon nach dem letzten Befehl im Skript.
- Nicht abgefangene Fehler durch fehlende
|| true-Absicherung bei optionalen Befehlen. - Fehlende Anführungszeichen um Variablen, die Leerzeichen enthalten könnten.
- Ausführung von Befehlen, die im eingeschränkten
PATHvon Logrotate nicht gefunden werden. - Ignorieren der
sharedscripts-Option bei mehreren Logdateien im selben Block. - Fehlende Berücksichtigung von SELinux- oder AppArmor-Richtlinien auf gehärteten Systemen.
Vergleich: Manuelle Rotation, Logrotate und systemd-journald
Nicht immer ist Logrotate die beste Wahl. Für systemd-Dienste bietet journald eine integrierte Alternative. Die folgende Tabelle vergleicht die Ansätze anhand von Kriterien, die in der Praxis entscheidend sind.
| Kriterium | Logrotate | Manuelle Rotation | systemd-journald |
|---|---|---|---|
| Konfigurationsaufwand | Mittel, eine Datei pro Dienst | Hoch, Skript pro Dienst | Niedrig, zentrale Konfiguration |
| Unterstützung für postrotate-Skripte | Ja, flexibel | Ja, aber fehleranfällig | Nein, nur Signale |
| Komprimierung | Integriert (gzip, bzip2, xz) | Manuell | Integriert, aber wenig konfigurierbar |
| Rotation nach Größe | Ja, präzise | Nein | Ja, aber grob |
| Überwachung | Extern erforderlich | Extern erforderlich | Integriert über journalctl |
| Empfehlung | Für klassische Dienste | Nur in Ausnahmen | Für systemd-native Dienste |
Häufig gestellte Fragen zu Logrotate und postrotate-Skripten
Warum wird mein postrotate-Skript ausgeführt, obwohl die Rotation fehlschlägt?
Logrotate führt postrotate aus, sobald die Datei umbenannt wurde, unabhängig davon, ob die Komprimierung erfolgreich war. Wenn die Komprimierung fehlschlägt, weil beispielsweise der Speicherplatz nicht ausreicht, wird das Skript trotzdem ausgeführt. Der Dienst öffnet dann eine neue Datei, während die alte unkomprimiert bleibt. Prüfen Sie den Exit-Code der Komprimierung und den verfügbaren Speicherplatz.
Wie kann ich testen, ob mein postrotate-Skript korrekt funktioniert, ohne echte Logs zu verlieren?
Erstellen Sie eine Testkonfiguration mit einer harmlosen Logdatei, etwa /tmp/test.log. Führen Sie logrotate -f /tmp/test.conf aus und beobachten Sie das Verhalten. So testen Sie den vollständigen Ablauf, ohne produktive Logs anzufassen. In meiner Praxis hat sich dieser Ansatz bewährt, um Skripte vor dem Einsatz zu validieren.
Was bedeutet der Fehlercode 1 in der Logrotate-Statusdatei?
Ein Exit-Code 1 bedeutet, dass ein Befehl im postrotate-Skript fehlgeschlagen ist. Die Statusdatei zeigt den Zeitstempel, aber nicht den fehlgeschlagenen Befehl. Führen Sie einen Debug-Lauf mit -d aus, um den genauen Befehl zu identifizieren. Häufig ist es ein fehlendes Semikolon oder ein nicht gefundener Befehl.
Muss ich Logrotate nach jeder Änderung neu starten?
Nein, Logrotate liest seine Konfiguration bei jedem Lauf neu ein. Ein Neustart ist nicht erforderlich. Allerdings wird die Konfiguration nur beim nächsten geplanten Lauf wirksam. Wenn Sie sofort testen wollen, erzwingen Sie einen Lauf mit -f. Beachten Sie, dass ein erzwungener Lauf die Rotation auch dann ausführt, wenn die Kriterien nicht erfüllt sind.
Wie gehe ich mit mehreren Diensten vor, die dasselbe Logverzeichnis verwenden?
Verwenden Sie für jeden Dienst einen eigenen Block in /etc/logrotate.d/. Achten Sie darauf, dass die Muster sich nicht überschneiden. Wenn zwei Blöcke dieselbe Datei erfassen, kann es zu Konflikten kommen. In meiner Erfahrung ist es besser, die Logdateien in getrennten Verzeichnissen zu halten, um Überschneidungen zu vermeiden.
Welche Rolle spielt systemd beim Auslösen von Logrotate auf modernen Distributionen?
Auf modernen Distributionen wird Logrotate von logrotate.timer ausgelöst, nicht von einem cron-Job. Der Timer ist Teil des systemd-Systems und bietet eine bessere Kontrolle über die Ausführung. Prüfen Sie mit systemctl status logrotate.timer, ob der Timer aktiv ist. Ein deaktivierter Timer ist eine häufige Ursache für ausbleibende Rotationen.
Zusammenfassung: In fünf Schritten von der Fehlermeldung zum stabilen postrotate-Skript
Die Fehlerbehebung folgt einem klaren Pfad. Beginnen Sie mit der Reproduktion, analysieren Sie die Konfiguration, testen Sie isoliert, korrigieren Sie die Umgebung und verifizieren Sie das Ergebnis. Mit dieser Methode lösen Sie die meisten Probleme in unter 30 Minuten.
- Fehler mit
logrotate -dreproduzieren und die genaue Zeile identifizieren. - Konfigurationsdatei auf Syntaxfehler und fehlende Semikolons prüfen.
- Skript isoliert mit
bash -xtesten und den Rückgabewert auswerten. - Berechtigungen, SELinux- und AppArmor-Richtlinien korrigieren.
- Korrektur mit einem erzwungenen Lauf verifizieren und eine Überwachung einrichten.
Ich empfehle, diese Schritte in Ihre Standardvorgehensweise bei der Systemverwaltung aufzunehmen. Ein robustes postrotate-Skript ist ein kleiner Baustein, aber ein entscheidender für die Resilienz Ihrer Infrastruktur.
Pour aller plus loin sur ce sujet, consultez aussi notre article sur Logrotate-Skripte einbinden.
Diese Anleitung ist besonders hilfreich, wenn es um die spezifische Logrotate-Konfiguration für Datenbanken geht, wo postrotate-Skripte kritisch sind.




