Log-Dateien wachsen unaufhörlich. Ein unkontrolliert wachsendes /var/log kann ein gesamtes Linux-System zum Stillstand bringen, wenn die Root-Partition vollläuft. Logrotate ist das Standardwerkzeug unter Linux, um Log-Dateien automatisch zu rotieren, komprimieren und löschen. Zusammen mit dem Systemd Journal bildet es die Grundlage für professionelles Log-Management auf jedem Server.
Wie Logrotate funktioniert
Logrotate wird typischerweise als Cron-Job oder Systemd-Timer einmal täglich ausgeführt. Bei jedem Lauf prüft es seine Konfiguration und entscheidet für jede Log-Datei, ob eine Rotation notwendig ist.
Der Rotationsprozess:
access.log → access.log.1 (aktuelle Datei wird umbenannt)
access.log.1 → access.log.2 (vorherige Rotation verschoben)
access.log.2 → access.log.3 (usw.)
access.log.3 → access.log.3.gz (komprimiert)
access.log.4.gz → (gelöscht) (älteste Datei entfernt)
Auslösung
# Systemd-Timer prüfen (moderne Distributionen)
systemctl status logrotate.timer
# Oder klassischer Cron-Job
cat /etc/cron.daily/logrotate
Grundkonfiguration
Hauptkonfiguration: /etc/logrotate.conf
cat /etc/logrotate.conf
# Globale Standardeinstellungen
weekly # Wöchentliche Rotation
rotate 4 # 4 Versionen behalten
create # Neue Log-Datei nach Rotation erstellen
dateext # Datum statt Nummer im Dateinamen
compress # Rotierte Dateien komprimieren (gzip)
delaycompress # Erst bei nächster Rotation komprimieren
# Anwendungsspezifische Konfigurationen einbinden
include /etc/logrotate.d
Anwendungsspezifische Konfiguration
Jede Anwendung platziert ihre Logrotate-Konfiguration in /etc/logrotate.d/:
ls /etc/logrotate.d/
# apt dpkg nginx rsyslog samba ufw ...
Rotationsstrategien
Zeitbasierte Rotation
/var/log/nginx/access.log {
daily # Tägliche Rotation
rotate 30 # 30 Tage behalten
missingok # Kein Fehler wenn Datei fehlt
notifempty # Nicht rotieren wenn leer
compress # Mit gzip komprimieren
delaycompress # Erst beim nächsten Mal komprimieren
create 0640 www-data adm
sharedscripts
postrotate
[ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
}
| Direktive | Bedeutung |
|---|---|
daily | Tägliche Rotation |
weekly | Wöchentliche Rotation |
monthly | Monatliche Rotation |
yearly | Jährliche Rotation |
Größenbasierte Rotation
/var/log/application/app.log {
size 100M # Rotieren wenn > 100 MB
rotate 10 # 10 Versionen behalten
missingok
compress
copytruncate # Datei kopieren und leeren statt umbenennen
create 0644 appuser appgroup
}
Größenbasierte Rotation eignet sich für Anwendungen mit stark variierendem Log-Volumen. Statt täglich zu rotieren, wird nur rotiert, wenn eine definierte Schwelle überschritten wird.
Kombinierte Strategie
/var/log/syslog {
daily # Mindestens täglich prüfen
size 50M # Aber auch bei 50 MB rotieren
rotate 14 # 14 Versionen behalten
compress
delaycompress
missingok
notifempty
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
compress und delaycompress
compress
Die compress-Direktive komprimiert rotierte Log-Dateien mit gzip (Standard). Das spart erheblich Platz:
# Beispiel: Nginx Access-Log
ls -lh /var/log/nginx/
# access.log 12M (aktuelle Datei)
# access.log.1 12M (letzte Rotation, noch unkomprimiert)
# access.log.2.gz 1.8M (komprimiert, ~85% kleiner)
# access.log.3.gz 1.6M
Alternatives Komprimierungsverfahren:
compresscmd /usr/bin/zstd
compressoptions -T0 --rm
compressext .zst
uncompresscmd /usr/bin/unzstd
Zstd bietet bessere Komprimierungsraten als gzip bei höherer Geschwindigkeit.
delaycompress
delaycompress verzögert die Komprimierung um eine Rotation. Das ist wichtig, weil einige Anwendungen die gerade rotierte Datei noch offen haben:
Rotation 1: access.log → access.log.1 (unkomprimiert)
Rotation 2: access.log.1 → access.log.2.gz (jetzt komprimiert)
Ohne delaycompress würde access.log.1 sofort komprimiert. Programme, die noch Handles auf die alte Datei halten, könnten Fehler produzieren.
copytruncate vs. create
create (Standard)
create 0640 www-data adm
Logrotate benennt die Log-Datei um und erstellt eine neue leere Datei. Die Anwendung muss anschließend die neue Datei öffnen — das geschieht meist über ein postrotate-Script, das die Anwendung zum Reload auffordert.
copytruncate
copytruncate
Logrotate kopiert die Log-Datei und leert anschließend das Original. Die Anwendung bemerkt nichts, da der Datei-Handle bestehen bleibt.
Vorteil: Kein Reload der Anwendung nötig. Nachteil: Zwischen Kopieren und Leeren können Log-Zeilen verloren gehen (Race Condition).
| Methode | Vorteil | Nachteil | Empfehlung |
|---|---|---|---|
create | Keine Datenverluste | Anwendung muss neu laden | Standard für die meisten Dienste |
copytruncate | Kein Reload nötig | Potentieller Datenverlust | Für Anwendungen ohne Reload-Mechanismus |
postrotate Scripts
postrotate-Scripts werden nach jeder Rotation ausgeführt. Sie signalisieren der Anwendung, die neue Log-Datei zu verwenden.
Nginx
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
}
kill -USR1 weist Nginx an, die Log-Dateien neu zu öffnen, ohne den Dienst zu unterbrechen.
Apache
/var/log/apache2/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 root adm
sharedscripts
postrotate
if invoke-rc.d apache2 status > /dev/null 2>&1; then
invoke-rc.d apache2 reload > /dev/null
fi
endscript
}
PostgreSQL
/var/log/postgresql/postgresql-*.log {
weekly
rotate 10
compress
delaycompress
missingok
notifempty
create 0640 postgres adm
su postgres postgres
postrotate
/usr/lib/postgresql/16/bin/pg_ctl logrotate -D /var/lib/postgresql/16/main
endscript
}
sharedscripts
Die sharedscripts-Direktive ist wichtig bei Wildcard-Patterns: Ohne sie würde das postrotate-Script für jede rotierte Datei einzeln ausgeführt. Mit sharedscripts wird es nur einmal nach allen Rotationen aufgerufen.
Systemd Journal
Neben Logrotate verwaltet das Systemd Journal (journald) Logs aller Systemd-Units. Beide Systeme arbeiten parallel und ergänzen sich.
Journal-Konfiguration
# /etc/systemd/journald.conf
[Journal]
Storage=persistent # Logs auf Disk speichern (statt nur RAM)
SystemMaxUse=2G # Maximale Gesamtgröße
SystemMaxFileSize=128M # Maximale Größe pro Journal-Datei
MaxRetentionSec=90day # Maximales Alter
Compress=yes # Komprimierung aktivieren
ForwardToSyslog=yes # Auch an rsyslog weiterleiten
# Konfiguration anwenden
systemctl restart systemd-journald
# Journal-Größe prüfen
journalctl --disk-usage
Manuelles Aufräumen
# Journal auf 1 GB begrenzen
journalctl --vacuum-size=1G
# Einträge älter als 30 Tage löschen
journalctl --vacuum-time=30d
# Auf maximal 5 Dateien begrenzen
journalctl --vacuum-files=5
Journal vs. Logrotate
| Aspekt | Systemd Journal | Logrotate |
|---|---|---|
| Datenformat | Binär (strukturiert) | Textdateien |
| Zugriff | journalctl mit Filtern | cat, grep, less |
| Rotation | Automatisch (integriert) | Extern konfiguriert |
| Metadaten | Umfangreich (PID, Unit, Priority) | Nur Text |
| Anwendungen | Systemd-Units | Beliebige Log-Dateien |
Troubleshooting
Trockenlauf (Debug-Modus)
# Logrotate im Debug-Modus testen (keine Änderungen)
logrotate -d /etc/logrotate.conf
# Einzelne Konfiguration testen
logrotate -d /etc/logrotate.d/nginx
# Erzwungene Rotation (für Tests)
logrotate -f /etc/logrotate.d/nginx
Häufige Fehler
Fehler: „skipping because parent directory has insecure permissions”
# Verzeichnisrechte prüfen und korrigieren
chmod 755 /var/log/myapp
chown root:root /var/log/myapp
Fehler: „error: skipping because of taboo extension”
Logrotate ignoriert Dateien mit bestimmten Endungen (.rpmsave, .rpmorig, .dpkg-old). Eigene Konfigurationen müssen ohne solche Endungen benannt werden.
Fehler: Rotation findet nicht statt
# Status-Datei prüfen
cat /var/lib/logrotate/status
# Enthält den Zeitpunkt der letzten Rotation pro Datei:
# "/var/log/nginx/access.log" 2026-4-10-0:0:0
Best Practices
1. Monitoring der Log-Verzeichnisse
# Disk-Usage der wichtigsten Log-Verzeichnisse
du -sh /var/log/*/ 2>/dev/null | sort -rh | head -10
# Warnung bei über 80% Belegung der /var-Partition
VAR_USAGE=$(df /var --output=pcent | tail -1 | tr -d ' %')
if [ "$VAR_USAGE" -gt 80 ]; then
echo "WARNING: /var is ${VAR_USAGE}% full"
fi
2. Separate /var/log-Partition
Für Produktivserver empfiehlt sich eine dedizierte Partition für /var/log. So kann ein Logging-Problem niemals die Root-Partition füllen:
# Beispiel: 20 GB /var/log Partition
/dev/sda3 /var/log ext4 defaults,noexec,nosuid 0 2
3. Zentrale Log-Aggregation
Für Umgebungen mit mehreren Servern sollten Logs zentral gesammelt werden:
# rsyslog: Logs an zentralen Server weiterleiten
# In /etc/rsyslog.d/50-remote.conf
*.* @logserver.example.com:514 # UDP
*.* @@logserver.example.com:514 # TCP
4. Sicherheitsrelevante Logs schützen
Auth-Logs und Audit-Logs verdienen besondere Behandlung:
/var/log/auth.log {
daily
rotate 90 # 90 Tage aufbewahren (Compliance)
compress
delaycompress
missingok
notifempty
create 0640 root adm
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
90 Tage Aufbewahrung sicherheitsrelevanter Logs ist ein gängiger Standard in Compliance-Frameworks wie ISO 27001 oder BSI IT-Grundschutz.
Fazit
Logrotate ist ein unscheinbares, aber unverzichtbares Werkzeug auf jedem Linux-Server. Mit der richtigen Konfiguration — angepasst an das Log-Volumen und die Anforderungen der jeweiligen Anwendung — bleibt /var/log unter Kontrolle. In Kombination mit dem Systemd Journal und einer zentralen Log-Aggregation entsteht ein robustes Log-Management, das sowohl den Betrieb als auch Compliance-Anforderungen zuverlässig abdeckt.
Mehr zu diesen Themen:
Weitere Artikel
Backup-Strategie für KMU: Proxmox PBS + TrueNAS als zuverlässiges Backup-Konzept
Backup-Strategie für KMU mit Proxmox PBS und TrueNAS: 3-2-1-Regel umsetzen, PBS als primäres Backup-Target, TrueNAS-Replikation als Offsite-Kopie, Retention Policies und automatisierte Restore-Tests.
OPNsense Suricata Custom Rules: Eigene IDS/IPS-Signaturen schreiben und optimieren
Suricata Custom Rules auf OPNsense: Rule-Syntax, eigene Signaturen für interne Services, Performance-Tuning, Suppress-Lists und EVE-JSON-Logging.
Systemd Security: Linux-Services härten und absichern
Systemd Security-Hardening: Unit-Hardening mit ProtectSystem, PrivateTmp, NoNewPrivileges, CapabilityBoundingSet, systemd-analyze security, Sandboxing, Resource Limits und eigene Timer erstellen.