Logrotate Die erfolgreiche Originaldatei wird auf die Originalgröße zurückgesetzt

11

Hat jemand Probleme mit logrotate gehabt, die dazu geführt haben, dass eine Protokolldatei gedreht wurde und dann wieder die ursprüngliche Größe hatte? Hier sind meine Ergebnisse:

Logrotate-Skript:

/var/log/mylogfile.log {
    drehen 7
    Täglich
    komprimieren
    olddir / log_archives
    Missingok
    notifempty
    copytruncate
}}

Ausführliche Ausgabe von Logrotate:

Kopieren von /var/log/mylogfile.log nach /log_archives/mylogfile.log.1
Abschneiden von /var/log/mylogfile.log
Protokoll komprimieren mit: / bin / gzip
Entfernen des alten Protokolls /log_archives/mylogfile.log.8.gz

Protokolldatei nach dem Abschneiden passiert

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 Teil1 Teil1 0 11. Januar 17:32 /var/log/mylogfile.log

Buchstäblich Sekunden später:

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 Teil1 Teil1 3.5G 11. Januar 17:32 /var/log/mylogfile.log

RHEL Version:

[root @ server ~] # cat / etc / redhat-release 
Red Hat Enterprise Linux ES Version 4 (Nahant Update 4)

Logrotate Version:

[root @ DAA21529WWW370 ~] # rpm -qa | grep logrotate
logrotate-3.7.1-10.RHEL4

Einige Anmerkungen:

  • Der Dienst kann nicht sofort neu gestartet werden. Deshalb verwende ich copytruncate
  • Die Protokolle werden jede Nacht gedreht, je olddirnachdem, in welchem ​​Verzeichnis sich die Protokolldateien von jeder Nacht befinden.
Drawrockshard
quelle

Antworten:

18

Dies liegt wahrscheinlich daran, dass der Prozess, der in die Datei schreibt, trotz des Abschneidens der Datei mit dem zuletzt versetzten Versatz fortgesetzt wird. Was also passiert, ist, dass logrotate die Datei abschneidet, die Größe Null ist, der Prozess erneut in die Datei schreibt und mit dem Offset fortfährt, den sie aufgehört hat, und Sie haben jetzt eine Datei mit NULL-Bytes bis zu dem Punkt, an dem Sie sie abgeschnitten haben, plus der neuen Einträge in das Protokoll geschrieben.

od -c nach Abschneiden + plötzlichem Wachstum, erzeugte Ausgabe in der Richtung von:

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

Dies bedeutet, dass Ihre Datei von Offset 0 bis 33255657600 aus Null-Bytes und einigen lesbaren Daten besteht. Das Erreichen dieses Status dauert nicht so lange, bis alle diese Null-Bytes tatsächlich geschrieben sind. Die ext {2,3,4} -Dateisysteme unterstützen so genannte Sparse-Dateien. Wenn Sie also nach einer Region einer Datei suchen, die nichts enthält, wird angenommen, dass diese Region Null-Bytes enthält und keinen Speicherplatz beansprucht auf der Festplatte. Diese Null-Bytes werden nicht wirklich geschrieben, sondern nur als vorhanden angenommen. Daher dauert die Zeit, die benötigt wird, um auf 0 bis 3,5 GB zu gelangen, nicht lange. (Sie können die benötigte Zeit testen, indem dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1Sie Folgendes tun: In wenigen Millisekunden sollte eine Datei mit mehr als 3 GB erstellt werden.)

Wenn Sie ls -lsIhre Protokolldateien ausführen, nachdem sie abgeschnitten wurden und plötzlich wieder gewachsen sind, sollte jetzt am Anfang der Zeile eine Zahl angezeigt werden, die die tatsächliche Größe (in auf der Festplatte belegten Blöcken) darstellt, die wahrscheinlich Größenordnungen beträgt kleiner als die von nur gemeldete Größe ls -l.

Kjetil Jörgensen
quelle
Ich glaube nicht - in Sekunden geht die Protokolldatei von 0 Byte auf 3,5 GB. Die Gesamtzeit, die für die Fertigstellung des Logrotats benötigt wird, beträgt ca. 5 Minuten. Die Protokolldateien werden nicht so schnell geschrieben UND die Größe ist immer die Originalgröße, was zu zufällig erscheint.
Drawrockshard
Es sollte eine einfache Möglichkeit geben, dies zu überprüfen, die Datei zu überprüfen und festzustellen, ob tatsächlich etwas darin enthalten ist. Führen Sie zunächst od -c Dateiname | aus head -n 100. Wahrscheinlich werden Sie in ein paar Zeilen darüber informiert, dass es eine Lastwagenladung mit Null-Bytes sowie die neuesten Protokolleinträge gibt.
Kjetil Joergensen
Wenn dies der Fall ist, können wir dann testen, ob cat / dev / null> /var/log/mylogfile.log die Datei auf eine Weise abschneidet, die dieses Problem löst, anstatt die in copytruncate integrierte logrotate zu verwenden?
Mtinberg
2
Das Problem liegt nicht in der Art und Weise, wie die Datei abgeschnitten wird, sondern in der Art und Weise, wie das Programm die Protokolldatei schreibt. Damit das Abschneiden der Protokolldatei ein praktikabler Ansatz ist, muss das Programm in die Protokolldatei geschrieben werden, um Position 0 zu erreichen. Es ist möglich, dass ein Dateisystem, das keine Dateien mit geringer Dichte unterstützt, dieses Problem nicht hat, obwohl ich es nicht tue Ich habe momentan keine Möglichkeit, das zu testen.
Kjetil Joergensen
1
Diese endgültige Antwort war tatsächlich sinnvoller und die Lösung wird wahrscheinlich darin bestehen, die Anwendung neu zu starten.
Drawrockshard
2

Ich bin sehr zuversichtlich, dass Kjetil es geschafft hat. Drew, Sie sind vielleicht noch nicht von seiner Erklärung überzeugt, aber ich fordere Sie auf, sorgfältig zu lesen, was er gesagt hat.

Wenn Sie dies akzeptieren, müssen Sie entweder Ihre Anwendung stoppen und neu starten, wenn die Protokolle gedreht werden, oder ein Tool wie die "Rotatelogs" von Apache verwenden, bei dem Sie die Protokollausgabe über eine Pipe an das Tool weiterleiten und das Tool sich darum kümmert Drehen Sie die Protokolldatei von Zeit zu Zeit. Zum Beispiel protokolliert eine meiner Apache-Instanzen mit

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

was viele Protokolldateien mit Namen wie verursacht

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

erscheinen, ohne Apache neu zu starten; Ich kann sie dann nachträglich manuell komprimieren. Beachten Sie, wie die Rotation jede Woche durchgeführt wird, dh alle 604800 Sekunden, wobei dies das Argument ist, an das übergeben wird rotatelogs.

Wenn Sie die App nicht stoppen und neu starten können und sie nicht über eine Pipe protokolliert werden kann, haben Sie wahrscheinlich ein echtes Problem. Vielleicht haben andere Vorschläge.

MadHatter
quelle
0

Es wäre wirklich großartig, wenn Sie den gesamten Logrotate senden könnten.

Warum versuchen, kill -HUP zu verwenden? Methode (Klassisches Nachladen nicht Neustart ).

Überprüfen Sie außerdem, lsof wer auf die Datei zugreift.

Nikolaidis Fotis
quelle
Kann nicht verwendet werden, kill -HUPda diese Anwendung in keiner Weise berührt werden kann - es ist eine vertrauliche Anwendung, die ich nicht besitze (ich verwalte sie nicht einmal - ich verwalte nur die Betriebssystemseite), daher muss ich in der Lage sein, die Protokollierungen durchzuführen Weg.
Drawrockshard
1
Entschuldigung, die ursprüngliche Nachricht wurde frühzeitig übermittelt. Hier ist der Rest meiner ursprünglichen Nachricht: Ich habe mich heute Morgen beim System angemeldet und die Datei ist jetzt wieder normal, nachdem die geplante Anmeldung gestartet /etc/cron.dailywurde. Frage an alle: Gibt es etwas, das das logrotate-Skript anders macht als das manuelle Ausführen von logrotate? Mein Logrotate-Skript sieht buchstäblich so aus /usr/sbin/logrotate /etc/logrotate.conf. Das ist ziemlich verwirrend.
Drawrockshard
-1

Verwenden Sie einfach ">>", was "Anhängen" anstelle von ">" bedeutet, was bedeutet, dass Sie aus Ihren Skripten erstellen, die in diese Datei schreiben. Ich hatte genau das gleiche Problem und habe es mithilfe von Anhängen in meinem Skript behoben.

SomeScript.sh >> output.txt

Hoffe das ist klarer.

user578558
quelle
Es gibt keinen Hinweis darauf, dass das Schreiben in die Protokolldatei mithilfe >eines Skripts erfolgt. Darüber hinaus ist diese Antwort verwirrend, da es einen großen Unterschied zwischen >und >( )in Skripten gibt. Wenn der Code, der das Schreiben ausführt, aktualisiert wird, ist es viel besser, wenn er einfach mit dem Schreiben in die neue Protokolldatei beginnt, nachdem logrotateer seine Aufgabe erledigt hat.
Kasperd
Ich bearbeite meine Antwort so, dass sie klarer ist.
user578558