Logrotate rotiert, komprimiert und löscht Logdateien automatisch. Es verhindert, dass Logs die Festplatte füllen und hält die Logverwaltung übersichtlich.

Funktionsweise

Rotationsprozess

1. access.log (aktiv)
2. Rotation: access.log → access.log.1
3. Kompression: access.log.1 → access.log.1.gz
4. Alte Logs löschen: access.log.5.gz entfernt
5. Neue access.log erstellt

Konfiguration

Hauptkonfiguration

# /etc/logrotate.conf

# Wöchentliche Rotation
weekly

# 4 Rotationen behalten
rotate 4

# Neue leere Logdatei erstellen
create

# Komprimieren
compress

# Include App-spezifische Configs
include /etc/logrotate.d

App-spezifische Konfiguration

# /etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

Konfigurationsoptionen

Zeitbasierte Rotation

| Option | Beschreibung | |--------|--------------| | daily | Täglich rotieren | | weekly | Wöchentlich rotieren | | monthly | Monatlich rotieren | | yearly | Jährlich rotieren |

Größenbasierte Rotation

/var/log/myapp/*.log {
    size 100M        # Bei 100 MB rotieren
    rotate 10
    compress
}

# Kombiniert
/var/log/myapp/*.log {
    daily
    size 50M         # Täglich ODER bei 50 MB
    rotate 7
}

# Nur Größe
/var/log/myapp/*.log {
    maxsize 100M     # Rotation wenn > 100 MB
    minsize 10M      # Nicht rotieren wenn < 10 MB
}

Allgemeine Optionen

| Option | Beschreibung | |--------|--------------| | rotate N | N Rotationen behalten | | compress | Gzip-Kompression | | delaycompress | Erst bei nächster Rotation komprimieren | | nocompress | Nicht komprimieren | | compresscmd | Komprimierungsbefehl (default: gzip) | | compressoptions | Komprimierungsoptionen | | dateext | Datum statt Nummer als Extension | | dateformat | Format für dateext | | extension | Extension für rotierte Dateien | | missingok | Kein Fehler wenn Datei fehlt | | notifempty | Leere Dateien nicht rotieren | | ifempty | Leere Dateien rotieren | | create | Neue leere Datei erstellen | | nocreate | Keine neue Datei erstellen | | copytruncate | Kopieren und Original leeren | | copy | Nur kopieren, Original behalten | | olddir | Rotierte Logs in anderes Verzeichnis | | maxage | Logs nach N Tagen löschen |

Dateierstellung

/var/log/myapp/*.log {
    create 0640 www-data adm
    # Mode Owner Group
}

# Oder Rechte beibehalten
/var/log/myapp/*.log {
    create
    # Behält Original-Rechte
}

Praktische Beispiele

Apache

# /etc/logrotate.d/apache2

/var/log/apache2/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 640 root adm
    sharedscripts
    postrotate
        if invoke-rc.d apache2 status > /dev/null 2>&1; then
            invoke-rc.d apache2 reload > /dev/null
        fi
    endscript
}

MySQL

# /etc/logrotate.d/mysql-server

/var/log/mysql/*.log {
    daily
    rotate 7
    missingok
    create 640 mysql adm
    compress
    sharedscripts
    postrotate
        if [ -f /var/run/mysqld/mysqld.pid ]; then
            kill -HUP $(cat /var/run/mysqld/mysqld.pid)
        fi
    endscript
}

PHP-FPM

# /etc/logrotate.d/php-fpm

/var/log/php8.2-fpm/*.log {
    daily
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /var/run/php/php8.2-fpm.pid ] && kill -USR1 $(cat /var/run/php/php8.2-fpm.pid)
    endscript
}

Anwendungs-Logs

# /etc/logrotate.d/myapp

/var/log/myapp/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 0644 www-data www-data

    # Logs mit Datum
    dateext
    dateformat -%Y%m%d

    # Alte Logs in separates Verzeichnis
    olddir /var/log/myapp/archive

    # Script nach Rotation
    postrotate
        systemctl reload myapp || true
    endscript
}

Docker Container

# /etc/logrotate.d/docker-containers

/var/lib/docker/containers/*/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    copytruncate
    maxsize 100M
}

Systemd Journal

# /etc/logrotate.d/journal (meist nicht nötig, da journald selbst rotiert)
# Besser: journald.conf anpassen

# /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M
SystemMaxFileSize=50M
MaxRetentionSec=1month

Scripts

prerotate/postrotate

/var/log/myapp/*.log {
    daily
    rotate 7

    # Vor der Rotation
    prerotate
        /usr/local/bin/pre-rotate-script.sh
    endscript

    # Nach der Rotation
    postrotate
        /usr/local/bin/post-rotate-script.sh
    endscript

    # Nur einmal pro Rotation (nicht pro Datei)
    sharedscripts
}

firstaction/lastaction

/var/log/myapp/*.log {
    # Ganz am Anfang
    firstaction
        echo "Starting rotation" | logger
    endscript

    # Ganz am Ende
    lastaction
        echo "Finished rotation" | logger
    endscript
}

Test und Debug

Konfiguration prüfen

# Syntax-Check
logrotate -d /etc/logrotate.conf

# Nur bestimmte Config
logrotate -d /etc/logrotate.d/nginx

# Verbose
logrotate -v /etc/logrotate.conf

Manuelle Rotation

# Forcierte Rotation
logrotate -f /etc/logrotate.conf

# Einzelne Config forcieren
logrotate -f /etc/logrotate.d/nginx

# Mit Debug-Output
logrotate -d -f /etc/logrotate.d/myapp

Status-Datei

# Status prüfen
cat /var/lib/logrotate/status

# Status zurücksetzen (erzwingt Rotation)
> /var/lib/logrotate/status

Häufige Probleme

Log wird nicht rotiert

# 1. Syntax prüfen
logrotate -d /etc/logrotate.d/myapp

# 2. Status prüfen
cat /var/lib/logrotate/status | grep myapp

# 3. Forcieren
logrotate -f /etc/logrotate.d/myapp

# 4. Berechtigungen
ls -la /var/log/myapp/

Anwendung schreibt in alte Datei

# Lösung 1: copytruncate (keine Signale nötig)
/var/log/myapp/*.log {
    copytruncate
}

# Lösung 2: Service neu laden
/var/log/myapp/*.log {
    postrotate
        systemctl reload myapp
    endscript
}

Zu viele offene Dateien

# Wildcard einschränken
/var/log/myapp/app.log /var/log/myapp/error.log {
    # statt /var/log/myapp/*.log
}

# Oder: maxopen
/var/log/myapp/*.log {
    maxage 7
}

Cron-Integration

Automatischer Aufruf

# Standard: /etc/cron.daily/logrotate
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf

Eigener Zeitplan

# /etc/cron.d/logrotate-hourly
0 * * * * root /usr/sbin/logrotate /etc/logrotate.d/myapp-hourly

Zusammenfassung

| Option | Beschreibung | |--------|--------------| | daily/weekly | Rotations-Intervall | | rotate N | Anzahl behalten | | compress | Komprimieren | | delaycompress | Verzögert komprimieren | | copytruncate | Kopieren und leeren | | create | Neue Datei erstellen | | missingok | Fehlende OK | | notifempty | Leere nicht rotieren | | postrotate | Script nach Rotation |

| Befehl | Funktion | |--------|----------| | logrotate -d | Debug/Test | | logrotate -f | Forcieren | | logrotate -v | Verbose |

| Datei | Funktion | |-------|----------| | /etc/logrotate.conf | Hauptkonfiguration | | /etc/logrotate.d/ | App-Konfigurationen | | /var/lib/logrotate/status | Status-Datei |

Fazit

Logrotate ist essentiell für die Logverwaltung auf Linux-Servern. Die flexible Konfiguration ermöglicht präzise Kontrolle über Rotation und Aufbewahrung. copytruncate löst Probleme mit Anwendungen, die Dateien offen halten. postrotate-Scripts ermöglichen nahtlose Integration mit Services. Regelmäßige Tests mit logrotate -d verhindern Überraschungen.