System.out.println vs Logger

1. Warum Logger?

Während Sie ein Programm schreiben oder eine Produktionsanwendung für Unternehmen entwickeln, scheint die Verwendung von System.out.println die einfachste und einfachste Option zu sein. Es müssen keine zusätzlichen Bibliotheken zum Klassenpfad hinzugefügt und keine zusätzlichen Konfigurationen vorgenommen werden.

Die Verwendung von System.out.println bringt jedoch mehrere Nachteile mit sich, die sich in vielen Situationen auf die Benutzerfreundlichkeit auswirken. In diesem Tutorial werden wir diskutieren, warum und wann wir einen Logger über einfaches altes System.out und System.err verwenden möchten . Wir zeigen auch einige kurze Beispiele mit dem Log4J2-Protokollierungsframework.

2. Setup

Bevor wir beginnen, schauen wir uns die erforderlichen Maven-Abhängigkeiten und -Konfigurationen an.

2.1. Maven-Abhängigkeiten

Beginnen wir mit dem Hinzufügen der Log4J2-Abhängigkeit zu unserer pom.xml :

 org.apache.logging.log4j log4j-api 2.12.1   org.apache.logging.log4j log4j-core 2.12.1 

Wir können die neuesten Versionen von log4j-api und log4j-core auf Maven Central finden.

2.2. Log4J2-Konfiguration

Die Verwendung von System.out erfordert keine zusätzliche Konfiguration. Um Log4J2 verwenden zu können, benötigen wir jedoch eine Konfigurationsdatei log4j.xml :

Fast alle Logger-Frameworks erfordern eine gewisse Konfigurationsebene, entweder programmgesteuert oder über eine externe Konfigurationsdatei, wie die hier gezeigte XML-Datei.

3. Trennen der Protokollausgabe

3.1. System.out und System.err

Wenn wir unsere Anwendung auf einem Server wie Tomcat bereitstellen, verwendet der Server einen eigenen Logger. Wenn wir System.out verwenden , landen die Protokolle in Catalina.out . Es ist viel einfacher, unsere Anwendung zu debuggen, wenn Protokolle in einer separaten Datei abgelegt werden. Bei Log4j2 müssen wir einen Datei-Appender in die Konfiguration aufnehmen, um Anwendungsprotokolle in einer separaten Datei zu speichern.

Außerdem gibt es mit System.out.println keine Kontrolle oder Filterung darüber, welche Protokolle gedruckt werden sollen. Die einzige Möglichkeit, die Protokolle zu trennen, besteht darin, System.out.println für Informationsprotokolle und System.err.println für Fehlerprotokolle zu verwenden:

System.out.println("This is an informational message"); System.err.println("This is an error message");

3.2. Log4J2-Protokollierungsstufen

In Debug- oder Entwicklungsumgebungen möchten wir alle Informationen sehen, die die Anwendung druckt. In einer Live-Unternehmensanwendung bedeuten jedoch mehr Protokolle eine Erhöhung der Latenz. Logger-Frameworks wie Log4J2 bieten mehrere Steuerelemente auf Protokollebene:

  • TÖDLICH
  • ERROR
  • WARNEN
  • DIE INFO
  • DEBUGGEN
  • SPUR
  • ALLE

Mit diesen Ebenen können wir leicht filtern, wann und wo welche Informationen gedruckt werden sollen :

logger.trace("Trace log message"); logger.debug("Debug log message"); logger.info("Info log message"); logger.error("Error log message"); logger.warn("Warn log message"); logger.fatal("Fatal log message");

Wir können die Ebenen auch für jedes Quellcode-Paket einzeln konfigurieren. Weitere Informationen zur Konfiguration auf Protokollebene finden Sie in unserem Artikel zur Java-Protokollierung.

4. Protokolle in Dateien schreiben

4.1. Umleiten von System.out und System.err

Es ist möglich, Route System.out.println in eine Datei , die mit System.setOut () Methode:

PrintStream outStream = new PrintStream(new File("outFile.txt")); System.setOut(outStream); System.out.println("This is a baeldung article");

Und im Fall von System.err :

PrintStream errStream = new PrintStream(new File("errFile.txt")); System.setErr(errStream); System.err.println("This is a baeldung article error");

Wenn Sie die Ausgabe mit System.out oder System.err in eine Datei umleiten , können wir die Dateigröße nicht steuern. Daher wächst die Datei für die Dauer der Ausführung der Anwendung weiter.

Mit zunehmender Dateigröße kann es schwierig sein, diese größeren Protokolle zu öffnen oder zu analysieren.

4.2. Protokollierung in Dateien mit Log4J2

Log4J2 bietet einen Mechanismus zum systematischen Schreiben von Protokollen in Dateien und zum Rollen der Dateien basierend auf bestimmten Richtlinien. Zum Beispiel können wir die zu rollierenden Dateien basierend auf einem Datums- / Zeitmuster konfigurieren :

Oder wir können die Dateien basierend auf der Größe rollen, sobald sie einen bestimmten Schwellenwert erreicht haben :

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

5. Protokollierung bei externen Systemen

Wie wir im vorherigen Abschnitt gesehen haben, ermöglichen Logger-Frameworks das Schreiben der Protokolle in eine Datei. In ähnlicher Weise bieten sie auch Appender zum Senden von Protokollen an andere Systeme und Anwendungen . Dies ermöglicht das Senden von Protokollen an einen Kafka Stream oder eine Elasticsearch-Datenbank mithilfe von Log4J-Appendern anstelle von System.out.println.

Weitere Informationen zur Verwendung solcher Appender finden Sie in unserem Log4j-Appender-Artikel.

6. Anpassen der Protokollausgabe

Mithilfe von Loggern können wir anpassen, welche Informationen zusammen mit der eigentlichen Nachricht gedruckt werden sollen. Zu den Informationen, die wir drucken können, gehören der Paketname, die Protokollebene, die Zeilennummer, der Zeitstempel, der Methodenname usw.

While this would be possible with System.out.println, it would require a lot of manual work, while logging frameworks provide this functionality out of the box. With loggers, we can simply define a pattern in the logger configuration:

If we consider Log4J2 for our logger framework, there are several patterns that we can choose from or customize. Refer to the official Log4J2 documentation to learn more about them.

7. Conclusion

This article explains various reasons why to use a logger framework and why not to rely only on System.out.println for our application logs. While it is justifiable to use System.out.println for small test programs, we'd prefer not to use it as our main source of logging for an enterprise production application.

As always, the code examples in the article are available over on GitHub.