2.1 Erster Logger – log4j

Wie Sie bereits wissen, begann der Protokollverlauf mit System.err.println()der Ausgabe eines Datensatzes auf der Konsole. Es wird immer noch aktiv zum Debuggen verwendet, beispielsweise verwendet Intellij IDEA es, um Fehlermeldungen auf der Konsole anzuzeigen. Aber diese Option hat keine Einstellungen, also machen wir weiter.

Der erste und beliebteste Holzfäller hieß Log4j. Es war eine gute und hochgradig anpassbare Lösung. Aufgrund verschiedener Umstände gelangte diese Entscheidung nie in das JDK, was die gesamte Community sehr verärgerte.

Dieser Logger konnte nicht nur protokollieren, er wurde von Programmierern für Programmierer entwickelt und ermöglichte es ihnen, Probleme zu lösen, die im Zusammenhang mit der Protokollierung ständig auftraten.

Wie Sie bereits wissen, werden Protokolle am Ende so geschrieben, dass jemand sie liest und versucht zu verstehen, was während des Programmbetriebs passiert ist – was und wann wie erwartet schief gelaufen ist.

log4jDafür gab es drei Dinge :

  • Protokollierung von Unterpaketen;
  • Satz von Appendern (Ergebnisse);
  • Hot-Reload-Einstellungen.

Erstens könnten die Einstellungen log4jso geschrieben werden, dass die Protokollierung in einem Paket aktiviert und in einem anderen deaktiviert wird. Beispielsweise war es möglich, die Protokollierung im zu aktivieren com.codegym.server, in jedoch zu deaktivieren com.codegym.server.payment. Dadurch war es möglich, unnötige Informationen schnell aus dem Protokoll zu entfernen.

Zweitens log4jermöglichte es das gleichzeitige Schreiben von Protokollierungsergebnissen in mehrere Protokolldateien. Und die Ausgabe an jeden konnte individuell konfiguriert werden. Beispielsweise war es in einer Datei möglich, nur Informationen zu schwerwiegenden Fehlern zu schreiben, in einer anderen - Protokolle von einem bestimmten Modul und in einer dritten - Protokolle für eine bestimmte Zeit.

Jede Protokolldatei wurde somit auf einen bestimmten Typ des erwarteten Problems abgestimmt. Dies vereinfacht das Leben von Programmierern erheblich, die nicht gerne manuell Gigabyte-Protokolldateien durchsuchen.

Und schließlich, drittens, log4jwar es möglich, die Protokolleinstellungen direkt während der Ausführung des Programms zu ändern, ohne es neu starten zu müssen. Dies war sehr praktisch, wenn die Arbeit der Protokolle korrigiert werden musste, um zusätzliche Informationen zu einem bestimmten Fehler zu finden.

Wichtig! Es gibt zwei Versionen des Protokolls log4j: 1.2.x und 2.xx , die miteinander nicht kompatibel sind .

Sie können den Logger mit dem Code mit dem Projekt verbinden:

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
  </dependency>

  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
  </dependency>
</dependencies>

2.2 Erster offizieller Logger – JUL: java.util.logging

Nachdem der Logger-Zoo in der Java-Community aufgetaucht war, JDKbeschlossen die Entwickler, einen Standard-Logger zu erstellen, den jeder verwenden würde. So erschien der Logger JUL: Paket java.util.logging.

Bei seiner Entwicklung haben die Entwickler des Loggers jedoch nicht als Grundlage genommen log4j, sondern eine Variante des Loggers von IBM, die seine Entwicklung beeinflusst hat. Die gute Nachricht ist, dass der Logger JULim Lieferumfang enthalten ist JDK, die schlechte Nachricht ist, dass ihn nur wenige Leute nutzen.

JULI

Die Entwickler haben nicht nur „einen weiteren universellen Standard“JUL erstellt , sondern auch ihre eigenen Protokollierungsstufen dafür erstellt, die sich von denen unterschieden, die damals von gängigen Protokollierern akzeptiert wurden.

Und das war ein großes Problem. Schließlich werden Produkte Javahäufig aus einer großen Anzahl von Bibliotheken gesammelt, und jede dieser Bibliotheken verfügte über einen eigenen Logger. Daher war es notwendig, alle Logger zu konfigurieren, die in der Anwendung vorhanden sind.

Obwohl der Logger selbst ziemlich gut ist. Das Erstellen eines Loggers ist mehr oder weniger das Gleiche. Dazu müssen Sie Folgendes importieren:


java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());

Der Klassenname wird speziell übergeben, um zu wissen, woher die Protokollierung kommt.

Erst mit der Veröffentlichung haben die Entwickler wichtige Probleme gelöst, danach JUList die Nutzung wirklich komfortabel. Davor war es eine Art zweitklassiger Logger.

Dieser Logger unterstützt auch Lambda-Ausdrücke und verzögerte Auswertung. Beginnend mit Java 8können Sie bestehen Supplier<String>. Dies hilft, einen String nur dann zu lesen und zu erstellen, wenn er wirklich benötigt wird, und nicht jedes Mal, wie es vorher der Fall war.

Methoden mit einem Argument Supplier<String> msgSuppliersehen so aus:

public void info(Supplier msgSupplier) {
   log(Level.INFO, msgSupplier);
}

2.3 Erster Logger-Wrapper – JCL: Jakarta Commons Logging

Lange Zeit gab es keinen einheitlichen Standard für Holzfäller, er JULhätte einer werden sollen, aber es war noch schlimmer log4j, sodass nie ein einziger Standard erschien. Doch es entstand ein ganzer Zoo von Holzfällern, von denen jeder gleich werden wollte.

JCL

Den gewöhnlichen Java-Entwicklern gefiel jedoch nicht, dass fast jede Bibliothek über einen eigenen Logger verfügt und irgendwie auf besondere Weise konfiguriert werden muss. Aus diesem Grund hat die Community beschlossen, einen speziellen Wrapper für andere Logger zu erstellen – und zwar soJCL: jakarta commons logging

Und wieder wurde das Projekt, das als Führungspersönlichkeit ins Leben gerufen wurde, nicht zu einer solchen. Sie können keinen Gewinner erschaffen, Sie können nur ein Gewinner werden. Die Funktionalität JCLwar sehr schlecht und niemand wollte sie nutzen. Der Logger, der alle Logger ersetzen sollte, erlitt das gleiche Schicksal, da er JULnicht verwendet wurde.

Obwohl es zu vielen von der Apache-Community veröffentlichten Bibliotheken hinzugefügt wurde, ist der Zoo der Logger nur noch größer geworden.

2.4 Erster letzter Logger – Logback

Aber das ist nicht alles. Der Entwickler entschied, dass er der intelligenteste war (naja, weil sein Logger von den meisten Leuten benutzt wurde) und beschloss, einen neuen, verbesserten Logger zu schreiben, der die Vorteile anderer Logger log4jvereinen würde .log4j

Der neue Logger hieß Logback. Es war dieser Logger, der der zukünftige Single-Logger werden sollte, den jeder nutzen würde. Es basierte auf der gleichen Idee wie in log4j.

Sie können diesen Logger mit dem folgenden Code mit dem Projekt verbinden:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

Die Unterschiede bestanden in Logback:

  • verbesserte Leistung;
  • native Unterstützung hinzugefügt slf4j;
  • erweiterte Filtermöglichkeit.

Ein weiterer Vorteil dieses Loggers war, dass er über sehr gute Standardeinstellungen verfügte. Und Sie mussten den Logger nur dann konfigurieren, wenn Sie etwas daran ändern wollten. Außerdem wurde die Einstellungsdatei besser an die Unternehmenssoftware angepasst – alle ihre Konfigurationen wurden als festgelegt xml/.

Standardmäßig Logbacksind keine Einstellungen erforderlich und alle Protokolle ab der Stufe werden aufgezeichnet DEBUG. Wenn Sie ein anderes Verhalten benötigen, können Sie es über die Konfiguration konfigurieren xml:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
        </encoder>
    </appender>
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

2.5 Neuester universeller Logger – SLF4J: Einfache Logging-Fassade für Java

Wie lange kann es dauern, die goldene Mitte zu finden ...

Im Jahr 2006 verließ einer der Entwickler log4jdas Projekt und beschloss, es noch einmal zu versuchen, einen universellen Logger zu entwickeln. Diesmal handelte es sich jedoch nicht um einen neuen Logger, sondern um einen neuen universellen Standard (Wrapper), der es verschiedenen Loggern ermöglichte, miteinander zu interagieren.

Dieser Logger hieß slf4j — Simple Logging Facade for Java, es war ein Wrapper um log4j, JUL, common-loggins and logback. Dieser Logger löste ein echtes Problem – die Verwaltung eines Zoos von Loggern, sodass jeder sofort damit begann, ihn zu nutzen.

Wir lösen die Probleme, die wir uns selbst schaffen, heldenhaft. Wie Sie sehen, ist der Fortschritt so weit fortgeschritten, dass wir einen Wrapper über dem Wrapper erstellt haben ...

Die Hülle selbst besteht aus zwei Teilen:

  • API, das in Anwendungen verwendet wird;
  • Implementierungen, die als separate Abhängigkeiten für jeden Logger hinzugefügt werden.

Sie können den Logger mit dem Code mit dem Projekt verbinden:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>

Es reicht aus, die richtige Implementierung anzuschließen und fertig: Das gesamte Projekt funktioniert damit.

2.6 Optimierung in slf4j

Slf4junterstützt alle neuen Funktionen wie String-Formatierung für die Protokollierung . Vorher gab es ein solches Problem. Nehmen wir an, Sie möchten eine Nachricht in das Protokoll drucken:

log.debug("User " + user + " connected from " + request.getRemoteAddr());

Es liegt ein Problem mit diesem Code vor. Angenommen, Ihre Anwendung läuft weiter productionund schreibt nichts in das Protokoll DEBUG-messages. Die Methode wird jedoch log.debug()trotzdem aufgerufen, und wenn sie aufgerufen wird, werden auch die folgenden Methoden aufgerufen:

  • user.toString();
  • request.getRemoteAddr();

Der Aufruf dieser Methoden verlangsamt die Anwendung. Ihr Aufruf wird nur während des Debuggens benötigt, sie werden aber trotzdem aufgerufen.

Aus logischer Sicht musste dieses Problem in der Protokollierungsbibliothek selbst gelöst werden. Und in der ersten Version von log4j kam die Lösung:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}

Statt einer Zeile für das Protokoll mussten nun drei geschrieben werden. Dies verschlechterte die Lesbarkeit des Codes erheblich und verringerte die Popularität von log4j.

Der Logger slf4jkonnte die Situation leicht verbessern, indem er Smart Logging anbot. Es sah so aus:

log.debug("User {} connected from {}", user, request.getRemoteAddr());

Dabei {}bezeichnen sie das Einfügen von Argumenten, die in der Methode übergeben werden. Das heißt, der erste {}entspricht dem Benutzer, der zweite {}dem request.getRemoteAddr().

Diese Parameter werden nur dann zu einer einzigen Nachricht verkettet, wenn die Protokollierungsebene eine Protokollierung zulässt. Nicht perfekt, aber besser als alle anderen Optionen.

Danach SLF4Jerfreute es sich rasch wachsender Beliebtheit, im Moment ist dies die beste Lösung.

Daher betrachten wir die Protokollierung am Beispiel eines Bundles slf4j-log4j12.