Zum Inhalt springen

Log-Rotation und Dienst-Logs

Log-Dateien wachsen unbegrenzt — ohne Rotation würden sie irgendwann die Festplatte füllen. logrotate ist das Standardwerkzeug zum automatischen Verwalten von Log-Dateien: rotieren, komprimieren, löschen.

Terminal-Fenster
/etc/logrotate.conf # globale Standardwerte
/etc/logrotate.d/ # Dienst-spezifische Konfigurationen

Beispiel /etc/logrotate.conf:

# Globale Defaults
weekly # wöchentlich rotieren
rotate 4 # 4 alte Versionen behalten
compress # komprimieren (gzip)
delaycompress # aktuelle Rotation erst beim nächsten Lauf komprimieren
missingok # kein Fehler wenn Log-Datei fehlt
notifempty # nicht rotieren wenn Datei leer ist
# Einzelne Dienste einbinden:
include /etc/logrotate.d
/etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily # täglich rotieren
rotate 14 # 14 Tage aufbewahren
compress
delaycompress
missingok
notifempty
sharedscripts # pre/postrotate nur einmal ausführen (nicht pro Datei)
postrotate
nginx -s reopen # nginx: neue Log-Datei öffnen
endscript
}
DirektiveBedeutung
daily / weekly / monthlyRotationsintervall
rotate NN alte Versionen behalten, ältere löschen
compressältere Logs mit gzip komprimieren
delaycompresserst ab der übernächsten Rotation komprimieren
size 100Mrotieren wenn Datei größer als 100 MB (statt zeitbasiert)
missingokkein Fehler bei fehlender Log-Datei
notifemptynicht rotieren wenn Datei leer
create 640 root admneue Log-Datei mit diesen Rechten anlegen
dateextDatums-Suffix statt Nummer (syslog.2026-03-24)
postrotate / endscriptBefehl nach Rotation ausführen
copytruncateDatei kopieren und dann leeren (statt umbenennen)
Terminal-Fenster
sudo logrotate /etc/logrotate.conf # normale Ausführung
sudo logrotate --force /etc/logrotate.conf # erzwingen (auch wenn nicht fällig)
sudo logrotate --debug /etc/logrotate.conf # Trockenlauf — was würde passieren?

logrotate wird üblicherweise täglich als Cron-Job oder systemd-Timer ausgeführt:

Terminal-Fenster
systemctl list-timers | grep logrotate
cat /etc/cron.daily/logrotate
Terminal-Fenster
tail -f /var/log/nginx/access.log # Zugriffe live
tail -f /var/log/nginx/error.log # Fehler live
# Häufig aufgerufene URLs
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# HTTP-Statuscodes zählen
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# IP-Adressen mit den meisten Zugriffen
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

Log-Format in /etc/nginx/nginx.conf:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
Terminal-Fenster
tail -f /var/log/apache2/access.log # Debian/Ubuntu
tail -f /var/log/httpd/access_log # RHEL/Fedora
tail -f /var/log/apache2/error.log

Viele moderne Dienste schreiben nur ins Journal, nicht nach /var/log/. Die logrotate-Konfiguration für das Journal ist über journald.conf geregelt (siehe Journal).

Terminal-Fenster
journalctl -u mariadb -f # MariaDB-Logs live
journalctl -u postgresql --since today

Eigene Log-Datei für einen systemd-Dienst einrichten

Abschnitt betitelt „Eigene Log-Datei für einen systemd-Dienst einrichten“

In der Unit-Datei:

[Service]
StandardOutput=append:/var/log/mein-dienst.log
StandardError=append:/var/log/mein-dienst.log

Dazu eine passende logrotate-Konfiguration in /etc/logrotate.d/mein-dienst.

Wenn viele Logs aus verschiedenen Quellen durchsucht werden müssen:

Terminal-Fenster
# Alle Logs eines bestimmten Tags durchsuchen
grep -r "Fehler" /var/log/ 2>/dev/null
# Nur Text-Logs (keine Binärdateien)
grep -r --include="*.log" "connection refused" /var/log/
# Mit journalctl alle Quellen auf einmal
journalctl --since "1 hour ago" -p err