Logrotate-Rekursion
Was funktioniert nicht?
Eigentlich wollte ich logrotate nutzen, um meine Logs täglich zu bereinigen und so Datensparsamkeit umzusetzen: So können IP-Adressen, die ich für’s Banning brauche, einheitlich und automatisiert nach kurzer Zeit gelöscht werden. Die Server-Logs interessieren mich ansonsten überhaupt nicht und stehlen mir nur Speicherplatz.
Mit meiner aktuellen Konfiguration erstellt logrotate
zwar eine Logdatei am Tag, nennt sie aber xyz.log.1, xyz.log.1.1, xyz.log.1.1.1
anstatt der erwarteten xyz.log.1, xyz.log.2, xyz.log.3
. Somit funktioniert die Löschroutine nicht mehr und die Anzahl der Logs wächst stetig.
Und warum?
Ich vermute, dass meine logrotate-Konfiguration fehlerhaft ist. Im Moment sieht sie wie folgt aus:
## LOGROTATE file named 'blog'
blog/* {
# it's ok if the file doesn't already exist
missingok
# Sets the logs to rotate in intervals
daily
# Tells the system to remove old logs and only keep the most recent rotated logs
rotate 7
# Rotated logs will be compressed and kept on disk if they are 10 MB or less.
size 10M
# compress and delaycompress: These two options are used together and indicate that
# rotated logs should be compressed (gzip) except for the most recent one.
compress
delaycompress
}
Wie üblich nehme ich als Erstes die Bedienungsanleitung zur Hilfe, die ich mittels man logrotate
in der Konsole aufrufe.
Dort steht, dass die zu rotierende Datei direkt angegeben (und nicht nur per “Wildcard” gewählt *
) werden kann. Außerdem kann ein Logverhalten auch auf mehrere Dateipfade angewendet werden, indem sie durch Leerzeichen getrennt vor die geschweifte Klammer gesetzt werden.
Das Sternchen scheint genau mein Problem mit den kaskadierenden Logs zu erzeugen: Dadurch wird nicht nur die eigentliche Zieldatei access.log
rotiert sondern auch alle bereits rotierten Dateien nochmal angefasst.
Die Lösung
Entsprechend der Bedienungsanleitung schreibe ich die Bearbeitungsvorschrift für Logrotate so um, dass ich statt fünf eigenen Vorschriften für die jeweiligen Logs nur zwei Dateien erzeuge. Diese sind zudem einfacher und kürzer als die obige Ausgangsversion.
Beispiel:
# rotate webserver log files.
gitea/access.log
blog/access.log
landing/access.log
lectures/access.log
{
# Sets the logs to rotate in intervals
daily
# Tells the system to remove old logs and only keep the most recent rotated logs
rotate 7
# compress and delaycompress: These two options are used together and indicate that
# rotated logs should be compressed (gzip) except for the most recent one.
compress
delaycompress
}
Konfigurations-Update
Dies kann ich durch meine vorhandene Server-Konfigurations-Pipeline durch einfachen Push ins Repository auf dem Server ausrollen.
Nun muss ich die Dateien dort nur noch händisch nach /etc/logrotate.d
kopieren.
Logrotate testen
Jetzt wäre es noch schön, wenn ich ausprobieren könnte, ob die von mir vorgenommenen Änderungen auch tatsächlich funktionieren. Dafür nehme ich erneut die Bedienungsanleitung von logrotate zur Hilfe und tippe:
logrotate -d -v <LOGROTATE-DESCRIPTOR-FILE>
Mit aktivierten debug und verbose Flags wird logrotate die in der Konfigurationsdatei angegebene Rotationsvorschrift anwenden und Rückmeldung geben, tatsächlich auf dem Dateisystem aber keine Änderungen oder Rotationen durchführen. Bei mir sieht das Ergebnis des Tests dann etwa so aus:
lectures/access.log
after 1 days (7 rotations)
empty log files are rotated, old logs are removed
considering log gitea/access.log
Now: 2024-11-28 17:19
Last rotated at 2024-11-27 00:00
log needs rotating
considering log blog/access.log
Now: 2024-11-28 17:19
Last rotated at 2024-11-16 00:00
log needs rotating
considering log landing/access.log
Now: 2024-11-28 17:19
Last rotated at 2024-11-07 00:00
log needs rotating
considering log lectures/access.log
Now: 2024-11-28 17:19
Last rotated at 2024-09-21 00:00
log needs rotating
rotating log gitea/access.log, log->rotateCount is 7
[...]
renaming lectures/access.log.7.gz to lectures/access.log.8.gz (rotatecount 7, logstart 1, i 7),
renaming lectures/access.log.6.gz to lectures/access.log.7.gz (rotatecount 7, logstart 1, i 6),
renaming lectures/access.log.5.gz to lectures/access.log.6.gz (rotatecount 7, logstart 1, i 5),
renaming lectures/access.log.4.gz to lectures/access.log.5.gz (rotatecount 7, logstart 1, i 4),
renaming lectures/access.log.3.gz to lectures/access.log.4.gz (rotatecount 7, logstart 1, i 3),
renaming lectures/access.log.2.gz to lectures/access.log.3.gz (rotatecount 7, logstart 1, i 2),
renaming lectures/access.log.1.gz to lectures/access.log.2.gz (rotatecount 7, logstart 1, i 1),
renaming lectures/access.log.0.gz to lectures/access.log.1.gz (rotatecount 7, logstart 1, i 0)
[...]
Die Ausgabe zeigt mir, dass sowohl alle gewünschten Logdateien von logrotate berücksichtigt werden und auch, dass die Rotation korrekt und täglich durchgeführt wird.
Wieder etwas gelernt 😃