Eine Anleitung zu Rolling File Appendern

1. Übersicht

Während Protokolldateien häufig nützliche Informationen enthalten, werden sie im Laufe der Zeit natürlich größer, und wenn sie unbegrenzt wachsen dürfen, kann ihre Größe zu einem Problem werden.

Protokollierungsbibliotheken beheben dieses Problem mithilfe fortlaufender Dateianhänge, die die aktuelle Protokolldatei automatisch "rollen" oder archivieren und die Protokollierung in einer neuen Datei fortsetzen, wenn bestimmte vordefinierte Bedingungen auftreten, wodurch unerwünschte Ausfallzeiten vermieden werden.

In diesem Artikel erfahren Sie, wie Sie Rolling File Appender in einigen der am häufigsten verwendeten Protokollierungsbibliotheken konfigurieren - Log4j, Log4j2 und Slf4j.

Wir zeigen, wie Protokolldateien basierend auf Größe, Datum / Uhrzeit und einer Kombination aus Größe und Datum / Uhrzeit gerollt werden. Wir werden auch zeigen, wie Sie jede Bibliothek so konfigurieren, dass die alten Protokolldateien automatisch komprimiert und später gelöscht werden, damit wir keinen langwierigen Housekeeping-Code schreiben müssen.

2. Unsere Beispielanwendung

Beginnen wir mit einer Beispielanwendung, die einige Nachrichten protokolliert. Dieser Code basiert auf Log4j, kann jedoch problemlos für die Verwendung mit Log4j2 oder Slf4j geändert werden:

import org.apache.log4j.Logger; public class Log4jRollingExample { private static Logger logger = Logger.getLogger(Log4jRollingExample.class); public static void main(String[] args) throws InterruptedException { for(int i = 0; i < 2000; i++) { logger.info("This is the " + i + " time I say 'Hello World'."); Thread.sleep(100); } } }

Die Anwendung ist ziemlich naiv - sie schreibt einige Nachrichten in einer Schleife mit einer kurzen Verzögerung zwischen den Iterationen. Mit 2.000 auszuführenden Schleifen und einer Pause von 100 ms in jeder Schleife sollte die Anwendung etwas mehr als drei Minuten dauern.

In diesem Beispiel werden verschiedene Funktionen verschiedener Arten von Rolling File Appendern demonstriert.

3. Rolling File Appenders in Log4j

3.1. Maven-Abhängigkeiten

Um Log4j in Ihrer Anwendung zu verwenden, fügen Sie diese Abhängigkeit zunächst der Datei pom.xml Ihres Projekts hinzu :

 log4j log4j 1.2.17  

Fügen Sie die folgende Abhängigkeit hinzu, um die zusätzlichen Appender zu verwenden, die von Apache-Log-Extras bereitgestellt werden , die wir in den nächsten Beispielen verwenden werden. Verwenden Sie dabei dieselbe Version, die wir für Log4j deklariert haben, um die vollständige Kompatibilität sicherzustellen:

 log4j apache-log4j-extras 1.2.17  

Sie finden die neueste Version von Log4j und Apache Log4j Extras auf Maven Central.

3.2. Rollen basierend auf der Dateigröße

In Log4j wird wie in den anderen Protokollierungsbibliotheken das Rollen von Dateien an den Appender delegiert. Schauen wir uns die Konfiguration für einen Rolling File Appender in Log4j an, der basierend auf der Dateigröße rollt:

Hier haben wir Log4j mithilfe des MaxFileSize- Parameters so konfiguriert, dass die Protokolldatei rollt, wenn ihre Größe 5 KB erreicht . Wir haben Log4j außerdem angewiesen, maximal zwei gerollte Protokolldateien mit dem Parameter MaxBackupIndex zu speichern .

Als wir unsere Beispielanwendung ausgeführt haben, haben wir die folgenden Dateien erhalten:

27/11/2016 10:28 138 app.log 27/11/2016 10:28 5.281 app.log.1 27/11/2016 10:28 5.281 app.log.2 

Was ist passiert? Log4j begann mit dem Schreiben in die Datei app.log . Wenn die Dateigröße die 5-KB-Grenze überschritten hat, hat Log4j app.log in app.log.1 verschoben , ein brandneues, leeres app.log erstellt und weiterhin neue Protokollnachrichten in app.log geschrieben .

Nachdem das neue app.log die 5-KB-Grenze überschritten hatte, wurde dieser Rollvorgang wiederholt. Dieses Mal wurde app.log.1 in app.log.2 verschoben, um Platz für ein weiteres neues, leeres app.log zu schaffen .

Der fortlaufende Vorgang wurde während des Laufs mehrmals wiederholt. Da wir unseren Appender jedoch so konfiguriert haben, dass höchstens zwei gerollte Dateien gespeichert werden, gibt es keine Datei mit dem Namen app.log.3 .

Wir haben also eines der ursprünglichen Probleme gelöst, da wir jetzt eine Begrenzung für die Größe der erstellten Protokolldateien festlegen können.

Als wir andererseits die erste Zeile von app.log.2 überprüften , enthielt sie die Nachricht zur 700. Iteration, was bedeutet, dass alle vorherigen Protokollnachrichten verloren gegangen waren:

2016-11-27 10:28:34 INFO This is the 700 time I say 'Hello World'. 

Mal sehen, ob wir ein Setup entwickeln können, das besser für eine Produktionsumgebung geeignet ist, in der der Verlust von Protokollnachrichten nicht als der beste Ansatz angesehen werden kann.

Zu diesem Zweck werden wir andere leistungsstärkere, flexiblere und konfigurierbarere Log4j-Appender verwenden, die in einem speziellen Paket namens apache-log4j- extras geliefert werden .

Die in diesem Artefakt enthaltenen Appender bieten viele Optionen zur Feinabstimmung des Protokollrollens und führen die unterschiedlichen Konzepte zum Auslösen von Richtlinien und Rolling-Richtlinien ein . Die Auslöserichtlinie beschreibt, wann ein Wurf stattfinden soll, während die Rollrichtlinie beschreibt, wie der Wurf ausgeführt werden soll. Diese beiden Konzepte sind der Schlüssel zu fortlaufenden Protokolldateien und werden, wie wir gleich sehen werden, auch von anderen Bibliotheken mehr oder weniger explizit verwendet.

3.3. Rollen mit automatischer Komprimierung

Kehren wir zum Log4j-Beispiel zurück und verbessern Sie unser Setup, indem Sie die automatische Komprimierung der gerollten Dateien hinzufügen, um Platz zu sparen:

Mit dem auslösenden Richtlinienelement haben wir angegeben, dass der Roll erfolgen soll, wenn das Protokoll die Größe von 5.120 Byte überschreitet.

Innerhalb des fortlaufenden Richtlinien- Tags gibt der Parameter ActiveFileName den Pfad der Hauptprotokolldateien an, die die neuesten Nachrichten enthalten, und der Parameter FileNamePattern gibt eine Vorlage an, die beschreibt, welcher Pfad der gerollten Dateien sein soll. Beachten Sie, dass dies tatsächlich ein Muster ist, da der spezielle Platzhalter % i durch den Index der gerollten Datei ersetzt wird.

Beachten Sie auch, dass FileNamePattern mit der Erweiterung .gz“ endet . Immer wenn wir eine Erweiterung verwenden, die einem unterstützten komprimierten Format zugeordnet ist, werden die alten gerollten Dateien ohne zusätzlichen Aufwand von unserer Seite komprimiert.

Wenn wir nun die Anwendung ausführen, erhalten wir einen anderen Satz von Protokolldateien:

03/12/2016 19:24 88 app.1.log.gz ... 03/12/2016 19:26 88 app.2.log.gz 03/12/2016 19:26 88 app.3.log.gz 03/12/2016 19:27 70 app.current.log 

The file app.current.log is where the last logs occurred. Previous logs have been rolled and compressed when their size reached the set limit.

3.4. Rolling Based on Date and Time

In other scenarios, you may want to configure Log4j to roll the files based on the date and time of the log messages instead of the size of the file. In a web application, for instance, you may want to have all the log messages issued in one day in the same log file.

To do that, you can use the TimeBasedRollingPolicy. With this policy, it is mandatory to specify a template for the path of the log file that contains a time-related placeholder. Each time a log message is issued, the appender verifies what the resulting log path would be, and if it differs from the last used path, then a roll will occur. Here's a quick example that configures such an appender:

3.5. Rolling Based on Size and Time

Combining the SizeBasedTriggeringPolicy and the TimeBasedRollingPolicy, you can obtain an appender that rolls based on date/time, and when the size of the file reaches the set limit, it rolls based on size too:

When we ran our application with this setup, we obtained the following log files:

03/12/2016 19:25 234 app.19-25.1481393432120.log.gz 03/12/2016 19:25 234 app.19-25.1481393438939.log.gz 03/12/2016 19:26 244 app.19-26.1481393441940.log.gz 03/12/2016 19:26 240 app.19-26.1481393449152.log.gz 03/12/2016 19:26 3.528 app.19-26.1481393470902.log

The file app.19-26.1481393470902.log is where current logging takes place. As you can see, all the logs in the interval between 19:25 and 19:26 are stored in multiple compressed log files with names starting with “app.19-25″. The “%i” placeholder is replaced by an ever increasing number.

4. Rolling File Appenders in Log4j2

4.1. Maven Dependencies

To use Log4j2 as our preferred logging library, we need to update our project's POM with the following dependency:

 org.apache.logging.log4j log4j-core 2.7 

As usual, you can find the latest version on Maven Central.

4.2. Rolling Based on File Size

Let's change our example application to use the Log4j2 logging libraries and let's explore now how we can set up file rolling based on the size of the log file in the log4j2.xml configuration file:

  %d{yyyy-MM-dd HH:mm:ss} %p %m%n       

In the Policies tag, we specified all the triggering policies we want to apply. OnStartupTriggeringPolicy triggers a roll every time the application starts, which could be useful for stand-alone applications. We then specified a SizeBasedTriggeringPolicy stating that a roll should occur whenever the log file reaches 5KB.

4.3. Rolling Based on Date and Time

Using the policies offered by Log4j2, let's set up an appender to roll and compress the log file based on time:

  %d{yyyy-MM-dd HH:mm:ss} %p %m%n    

Here the key is the use of TimeBasedTriggeringPolicy that allows us to use time-related placeholders in the template of the rolled file names. Note that since we needed only a single triggering policy, we do not have to use the Policies tag as we did in the previous example.

4.4. Rolling Based on Size and Time

As previously described, a more compelling scenario is to roll and compress log files based on both time and size. Here is an example of how we can set up Log4j2 for this task:

  %d{yyyy-MM-dd HH:mm:ss} %p %m%n             

With this configuration, we stated that a roll should occur based on time and size. The appender is able to understand what time interval we're referring to because of the pattern used for the file name, “app.%d{MM-dd-yyyy-HH-mm}.%i.log.gz”, which implicitly sets a roll to occur every minute and compresses the rolled file.

We also added a DefaultRolloverStrategy to delete old rolled files matching certain criteria. We configure ours to delete files that match the given pattern when they are older than 20 days.

4.5. Maven Dependencies

To use Log4j2 as our preferred logging library, we need to update our project's POM with the following dependency:

 org.apache.logging.log4j log4j-core 2.7 

As usual, you can find the latest version on Maven Central.

5. Rolling File Appenders in Slf4j

5.1. Maven Dependencies

When you want to use Slf4j2 with a Logback backend as logging libraries, add this dependency to your pom.xml:

 ch.qos.logback logback-classic 1.1.7 

As usual, you can find the latest version on Maven Central.

5.2. Rolling Based on File Size

Let's see now how to use Slf4j instead, with its default back-end Logback. Let's explore how we can set up file rolling in the configuration file logback.xml, which is placed in the application's classpath:

 target/slf4j/roll-by-size/app.log  target/slf4j/roll-by-size/app.%i.log.zip 1 3 1MB   5KB   %-4relative [%thread] %-5level %logger{35} - %msg%n   

Again we encounter the concept of rolling policy. The basic mechanism is the same as that used by Log4j and Log4j2. The FixedWindowRollingPolicy allows us to use an index placeholder in the name pattern of the rolled file.

When the size of the log file grows over the configured limit, a new file is allocated, and the old content is stored as the first file of the list, shifting the existing ones one place further.

5.3. Rolling Based on Time

In Slf4j, we can roll a log file based on time using the provided TimeBasedRollingPolicy. This policy allows us to specify the template name of the rolling file using time and date related placeholders:

 target/slf4j/roll-by-time/app.log  target/slf4j/roll-by-time/app.%d{yyyy-MM-dd-HH-mm}.log.zip  20 1MB   %d{yyyy-MM-dd HH:mm:ss} %p %m%n  

5.4. Rolling Based on Size and Time

If you need to roll a file both based on both time and size, you can use the provided SizeAndTimeBasedRollingPolicy. When using this policy, you must specify both a time-related placeholder and an index placeholder.

Jedes Mal, wenn die Größe der Protokolldatei für ein bestimmtes Zeitintervall die konfigurierte Größenbeschränkung überschreitet, wird eine andere Protokolldatei mit demselben Wert für den zeitbezogenen Platzhalter, jedoch mit einem inkrementierten Index erstellt:

 target/slf4j/roll-by-time-and-size/app.log   target/slf4j/roll-by-time-and-size/app.%d{yyyy-MM-dd-mm}.%i.log.zip  5KB 20 1MB   %d{yyyy-MM-dd HH:mm:ss} %p %m%n  

6. Fazit

Wie wir gesehen haben, erspart Ihnen die Nutzung einer Protokollierungsbibliothek zum Rollen der Dateien die manuelle Verwaltung der Protokolldateien, sodass Sie sich auf die Entwicklung Ihrer Geschäftslogik konzentrieren können. Rolling File Appender sind ein wertvolles Werkzeug, das in der Toolbox jedes Entwicklers enthalten sein sollte.

Wie üblich finden Sie die Quellen auf GitHub, wo die in diesem Artikel vorgestellten Beispielanwendungen so konfiguriert sind, dass sie mit mehreren verschiedenen Rolling-Setups protokolliert werden, damit Sie eine gute Basiskonfiguration finden, die weiter an Ihre Anforderungen angepasst werden kann.