Warum erstellen JBoss und Logrotate Protokolldateien voller NUL-Zeichen?

7

Ich habe Logrotate so eingerichtet, dass meine JBoss Application Server 4.2.2.GA-Protokolle jede Nacht gedreht werden. Nachdem die Protokolldateien gedreht wurden und JBoss erneut mit dem Schreiben beginnt, beginnen die neuen Protokolldateien mit so vielen NUL-Zeichen, wie Zeichen in der vorherigen Protokolldatei vorhanden waren, gefolgt von den neuen Protokollnachrichten. Wenn die JBoss-Datei server.log beispielsweise 5000 Byte lang war, beginnt die neue Datei server.log nach der Drehung mit 5000 NUL-Zeichen. Nach einigen Tagen beginnt server.log mit NUL-Zeichen, die den Zeichen in allen Protokolldateien der vorherigen Tage zusammen entsprechen. Es scheint, als würde sich JBoss an seine Position in der Protokolldatei erinnern und dort weitermachen, wo es in der abgeschnittenen Datei aufgehört hat. Hier ist meine logrotate Konfiguration für JBoss:

/apps/jboss-4.2.2.GA/server/default/log/*log {
    daily
    rotate 30
    compress
    notifempty
    copytruncate
    missingok
    nocreate
}

Ich kann JBoss nicht jede Nacht neu starten, da dies zu viele Ausfallzeiten bedeuten würde. Ich kann den log4j DailyRollingFileAppender auch nicht verwenden, da er keine alten Protokolldateien löscht. Hat jemand Logrotate bekommen, der richtig mit JBoss funktioniert?

Ben Williams
quelle

Antworten:

7

Wir hatten das gleiche Problem mit einer Datei, die von log4j geschrieben wurde. Die Lösung bestand darin, die Eigenschaft "Anhängen" für den FileAppender auf "true" zu setzen. Nach dieser Änderung ist dieses Problem bei Dateien mit NUL nicht aufgetreten, wenn sie von einem externen Programm wie logrotate gedreht wurden.

Maitreya
quelle
Ja, wir haben die obige Logrotate-Konfiguration auch mit "Anhängen" erfolgreich verwendet. Ich bin mir nicht sicher, warum ich diese Frage nie aktualisiert habe. Vielen Dank.
Ben Williams
Nur ein Hinweis dazu: Die Log4J2-Entwickler sagen: "FileAppender funktioniert zwar gut mit logrotate, aber das ist eher zufällig als beabsichtigt." (Von hier aus )
FrontierPsycho
5

Aus meiner Erfahrung - und der Grund, warum wir logrotate nicht mit Log4j verwenden, ist, dass logrotate so funktioniert, dass es die Dateien umbenennt und dann das Programm anweist, seine Protokolle zu schließen und sie mit dem alten Dateinamen (der nicht mehr existiert) erneut zu öffnen ), normalerweise mit dem HUP-Signal.

Log4j kann jedoch nicht angewiesen werden, seine Protokolldateien erneut zu öffnen. Ich sehe, dass Sie copytruncatestattdessen die Dateien kopieren. Das Problem besteht darin, dass Log4j gepufferte Writer verwendet, die die aktuelle Position der zu schreibenden Datei verfolgen und das Protokoll abschneiden Die Datei log4j schreibt dort weiter, wo sie vor dem Abschneiden aufgehört hat zu schreiben. Abhängig von Ihrer Dateisystemimplementierung sollten hierdurch "Dateien mit Löchern" erstellt werden - dh die NULL-Zeichen, die Sie dort sehen, sind nicht wirklich vorhanden - die Datei ist tatsächlich nur so groß wie die tatsächlichen Daten, und das NULL-Zeichen ist die Art und Weise, wie Ihr Viewer die darstellt Loch. Einige Dateisysteme unterstützen dagegen keine Lücken und füllen die Datei tatsächlich mit NULL-Zeichen, wenn Log4j das Schreiben fortsetzt.

Ich schlage vor - verwenden Sie nicht logrotate, sondern finden Sie eine Möglichkeit, die Dateien in Log4j zu drehen, indem Sie einen RollingFileAppender (der das Entfernen alter Dateien unterstützt) oder den DailyRollingFileAppender und einen Cronjob verwenden, der alte Dateien extern entfernt (wie vorgesehen) ).

Guss
quelle
Vielen Dank. Das habe ich vermutet, aber ich hatte gehofft, dass es einen Weg gibt, logrotate zum Laufen zu bringen. Ich denke, ich muss DailyRollingFileAppender und einen benutzerdefinierten Cronjob verwenden.
Ben Williams
0

Das funktioniert perfekt. So fassen Sie zusammen, was @Guss vorgeschlagen hat:

1. Öffnen Sie Ihre "log4j.xml" und fügen Sie den folgenden Appender hinzu (ich habe die DailyRollingAppender-Klasse verwendet und für den täglichen Rollover konfiguriert):

* HINWEIS: Die Häufigkeit des Rollovers basiert auf dem "DatePattern". Siehe: http://www.codejava.net/coding/configure-log4j-for-creating-daily-rolling-log-files

<appender name="RollingAppender" class="org.apache.log4j.DailyRollingFileAppender">
       <param name="File" value="/logging_directory_path_here/server1.log" />
       <param name="DatePattern" value="'.'yyyy-MM-dd" />
       <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="[%p] %d %c %M - %m%n"/>          
       </layout>
    </appender>

    <root>
            <priority value="info" />
            <appender-ref ref="RollingAppender" />
    </root>
  1. Erstellen Sie ein Shell-Skript, das die Rollover-Protokolldatei komprimiert.
  2. Installieren Sie dieses Shell-Skript in der Crontab des Unix-Servers, damit es täglich ausgeführt wird. zB Wird täglich um 00:10 Uhr ausgeführt (Warum um 00:10 Uhr? Dies gibt log4j ausreichend Zeit, um den Rollover zu beenden, nur für den Fall, dass die Protokolldatei (en) zu groß sind / sind oder zu viele Protokolldateien vorhanden sind komprimieren).
  3. Stellen Sie schließlich sicher, dass der log4j-Rollover um 12:00 Uhr (Standard) und der Cron-Job, der das Shell-Skript ausführt, um 00:10 Uhr ausgeführt werden
Michael Co.
quelle