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.
logrotate
Abschnitt betitelt „logrotate“Konfiguration
Abschnitt betitelt „Konfiguration“/etc/logrotate.conf # globale Standardwerte/etc/logrotate.d/ # Dienst-spezifische KonfigurationenBeispiel /etc/logrotate.conf:
# Globale Defaultsweekly # wöchentlich rotierenrotate 4 # 4 alte Versionen behaltencompress # komprimieren (gzip)delaycompress # aktuelle Rotation erst beim nächsten Lauf komprimierenmissingok # kein Fehler wenn Log-Datei fehltnotifempty # nicht rotieren wenn Datei leer ist
# Einzelne Dienste einbinden:include /etc/logrotate.dEine typische Dienst-Konfiguration
Abschnitt betitelt „Eine typische Dienst-Konfiguration“/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}Wichtige Direktiven
Abschnitt betitelt „Wichtige Direktiven“| Direktive | Bedeutung |
|---|---|
daily / weekly / monthly | Rotationsintervall |
rotate N | N alte Versionen behalten, ältere löschen |
compress | ältere Logs mit gzip komprimieren |
delaycompress | erst ab der übernächsten Rotation komprimieren |
size 100M | rotieren wenn Datei größer als 100 MB (statt zeitbasiert) |
missingok | kein Fehler bei fehlender Log-Datei |
notifempty | nicht rotieren wenn Datei leer |
create 640 root adm | neue Log-Datei mit diesen Rechten anlegen |
dateext | Datums-Suffix statt Nummer (syslog.2026-03-24) |
postrotate / endscript | Befehl nach Rotation ausführen |
copytruncate | Datei kopieren und dann leeren (statt umbenennen) |
logrotate manuell ausführen
Abschnitt betitelt „logrotate manuell ausführen“sudo logrotate /etc/logrotate.conf # normale Ausführungsudo 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:
systemctl list-timers | grep logrotatecat /etc/cron.daily/logrotateDienst-spezifische Logs
Abschnitt betitelt „Dienst-spezifische Logs“tail -f /var/log/nginx/access.log # Zugriffe livetail -f /var/log/nginx/error.log # Fehler live
# Häufig aufgerufene URLsawk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# HTTP-Statuscodes zählenawk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# IP-Adressen mit den meisten Zugriffenawk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10Log-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;tail -f /var/log/apache2/access.log # Debian/Ubuntutail -f /var/log/httpd/access_log # RHEL/Fedora
tail -f /var/log/apache2/error.logsystemd-Dienste ohne eigene Log-Datei
Abschnitt betitelt „systemd-Dienste ohne eigene Log-Datei“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).
journalctl -u mariadb -f # MariaDB-Logs livejournalctl -u postgresql --since todayEigene 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.logStandardError=append:/var/log/mein-dienst.logDazu eine passende logrotate-Konfiguration in /etc/logrotate.d/mein-dienst.
Logs zentral durchsuchen
Abschnitt betitelt „Logs zentral durchsuchen“Wenn viele Logs aus verschiedenen Quellen durchsucht werden müssen:
# Alle Logs eines bestimmten Tags durchsuchengrep -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 einmaljournalctl --since "1 hour ago" -p err