„Oh, da bist du ja! Hast du dich daran erinnert, dass wir heute noch eine Unterrichtsstunde haben?“

„Nein, ich habe nur nach dir gesucht. Fast…“

„Ausgezeichnet, dann fangen wir an. Heute möchte ich Ihnen etwas über den Holzeinschlag erzählen.“

„Das Protokoll ist eine Liste der aufgetretenen Ereignisse. Fast wie ein Schiffstagebuch oder ein Tagebuch. Oder Twitter – vielleicht können Sie sich damit besser identifizieren. Es überrascht nicht, dass ein Logger ein Objekt ist, das Sie zum Protokollieren verwenden.“

„In der Programmierung ist es üblich, fast alles zu protokollieren. Und in Java protokollieren wir alles und sogar noch ein bisschen mehr.“

„Tatsache ist, dass Java-Programme sehr oft große Serveranwendungen ohne UI, Konsole usw. sind. Sie verarbeiten Tausende von Benutzeranfragen gleichzeitig, und es kommt oft zu verschiedenen Fehlern. Vor allem, wenn verschiedene Threads anfangen, sich gegenseitig zu stören.“

„Tatsächlich besteht die einzige Möglichkeit, unter diesen Umständen nach selten reproduzierbaren Fehlern und Ausfällen zu suchen, darin, alles zu protokollieren, was in jedem Thread passiert.“

„Meistens enthält das Protokoll Informationen über Methodenargumente, alle abgefangenen Fehler und viele Zwischeninformationen.“

„Je vollständiger das Protokoll, desto einfacher ist es, eine Abfolge von Ereignissen zu reproduzieren und die Ursachen von Fehlern oder Fehlern zu verfolgen.“

„Manchmal erreichen Protokolle mehrere Gigabyte pro Tag. Das ist normal.“

„Ein paar Gigabyte? O_o“

„Ja. Meistens werden Protokolldateien automatisch mit Angabe des jeweiligen Datums archiviert.“

„Wow.“

„Uh-huh. Anfangs hatte Java keinen eigenen Logger. Daher wurden mehrere unabhängige Logger geschrieben. Der häufigste davon war log4j.“

„Einige Jahre später bekam Java einen eigenen Logger, dessen Funktionalität jedoch weitaus schlechter war und er nicht weit verbreitet war.“

„Es ist eine Tatsache, dass Java einen offiziellen Logger hat, aber die gesamte Community der Java-Programmierer bevorzugt die Verwendung anderer Logger.

„Später wurden mehrere weitere Logger auf Basis von log4j geschrieben.“

„Dann wurde für alle der spezielle Universal-Logger slf4j geschrieben, der heute weit verbreitet ist. Er ist log4j sehr ähnlich, daher werde ich ihn als Beispiel verwenden, wenn ich die Protokollierung erkläre.“

„Der gesamte Protokollierungsprozess besteht aus drei Teilen.“

„ Sammeln Sie zunächst Informationen.“

Zweitens : Filtern Sie die gesammelten Informationen.“

Drittens notieren Sie die ausgewählten Informationen.“

„Beginnen wir mit der Sammlung. Hier ist ein typisches Beispiel einer Klasse, die protokolliert:“

Klasse mit Protokollierung
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.complete();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

„Achten Sie auf die rot hervorgehobenen Wörter.“

Zeile 3  – Erstellen Sie das Logger- Objekt. Ein solches statisches Objekt wird in fast jeder Klasse erstellt! Nun, außer in Klassen, die nichts anderes tun als Daten zu speichern.“

LoggerFactory ist eine spezielle Klasse zum Erstellen von Loggern und getLogger ist eine ihrer statischen Methoden. Normalerweise wird das aktuelle Objekt übergeben, es sind jedoch verschiedene Optionen möglich.“

Zeile 7 – Informationen zum Methodenaufruf werden in den Logger geschrieben. Beachten Sie, dass dies die erste Zeile der Methode ist. Sobald die Methode aufgerufen wird, schreiben wir sofort Informationen in das Protokoll.“

„Wir nennen die Debug-Methode, was bedeutet, dass die Wichtigkeit der Informationen auf DEBUG-Ebene liegt. Diese wird zum Filtern verwendet. Ich werde Ihnen in ein paar Minuten mehr darüber erzählen.“

Zeile 17 – Wir fangen eine Ausnahme ab und... schreiben sie sofort ins Protokoll! Genau das muss getan werden.“

„Dieses Mal rufen wir die Fehlermethode auf, die sofort anzeigt, dass die Informationen die Ebene FEHLER haben.“

Logger – 1

„Im Moment scheint alles klar zu sein. Na ja, soweit es mitten in unserem Gespräch klar werden kann.“

„Großartig, dann machen wir mit der Nachrichtenfilterung weiter.“

„Normalerweise hat jede Protokollnachricht ihre eigene Wichtigkeitsstufe, mit der Sie einige der Nachrichten verwerfen können. Hier sind die Wichtigkeitsstufen, die ich erwähnt habe:“

Wichtigkeitsstufe Beschreibung
ALLE Alle Nachrichten
VERFOLGEN Fein abgestimmte Debug-Meldungen
DEBUGGEN Wichtige Debug-Meldungen
DIE INFO Informationsnachrichten
WARNEN Warnungen
FEHLER Fehler
TÖDLICH Fatale Fehler
AUS Keine Nachrichten

Diese Ebenen werden auch beim Filtern von Nachrichten verwendet.

Angenommen, Sie setzen die Protokollierungsstufe auf WARN. Dann werden alle Nachrichten verworfen, die weniger wichtig als WARN sind: TRACE, DEBUG, INFO.

Wenn Sie die Filterstufe auf FATAL einstellen, werden auch ERROR-Meldungen verworfen.

„Beim Filtern werden zwei weitere Wichtigkeitsstufen verwendet: AUS, wodurch alle Nachrichten verworfen werden; und ALLE, wodurch alle Nachrichten angezeigt werden (nichts wird verworfen).“

„Wie und wo richte ich die Filterung ein?“

„Ich werde es dir ohne weitere Umschweife sagen.“

„Normalerweise werden die Log4j-Logger-Einstellungen in der Datei log4j.properties angegeben.“

Sie können in dieser Datei mehrere Appender-Objekte angeben. In diese Objekte werden Daten geschrieben. Es gibt Datenquellen und Appender – Objekte, die gegensätzliche Zwecke haben. Objekte, in die Daten wie Wasser fließen.

"Hier sind einige Beispiele:"

Anmeldung an der Konsole
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

Zeilen 1 und 4 – Dies sind Kommentare

Zeile 2 – Wir geben die gewünschte Protokollierungsstufe an. Alle weniger wichtigen Ebenen (DEBUG, TRACE) werden verworfen.

An derselben Stelle fügen wir ein Komma hinzu und geben dann den Namen des Objekts an (das wir uns selbst ausgedacht haben), in das das Protokoll geschrieben werden soll. Die Zeilen 5-9 enthalten die Einstellungen.

Zeile 5 – Wir geben den Typ des Appenders an ( ConsoleAppender ).

Zeile 6 – Wir geben genau an, wo wir schreiben ( System.out. ).

Zeile 7 – Wir legen die Klasse fest, die Konvertierungsmuster verwaltet (PatternLayout).

Zeile 8 – Wir legen das Konvertierungsmuster fest, das zum Schreiben verwendet wird. Im obigen Beispiel sind es Datum und Uhrzeit.

„Und so sieht das Schreiben in eine Datei aus:“

Protokollierung in einer Datei
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

„Zeile 2 legt die Nachrichtenfilterstufe und den Namen des Appender-Objekts (Senke) fest.“

„Zeile 5 – Wir geben den Datei-Appender-Typ ( RollingFileAppender ) an.“

„Zeile 6 – Wir geben den Namen der Datei an, in die das Protokoll geschrieben wird.“

„Zeile 7 – Wir geben die maximale Protokollgröße an. Wenn diese Größenbeschränkung überschritten wird, wird eine neue Datei erstellt.“

„Zeile 8 – Wir geben die Anzahl der zu speichernden alten Logdateien an.“

„Zeilen 9–10 – Konvertierungsmuster festlegen.“

„Ich weiß nicht, was hier passiert, aber ich kann es ahnen. Das ist ermutigend.“

„Das ist großartig. Dann ist hier ein Beispiel, wie man ein Protokoll in eine Datei und die Konsole schreibt:“

Protokollierung an der Konsole und einer Datei
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

„Ah, also kannst du das? Das ist großartig!“

„Ja. Sie können so viele Appender deklarieren, wie Sie möchten, und jeden einzelnen anpassen.“

Darüber hinaus kann jeder Appender sehr flexible Einstellungen zur Nachrichtenfilterung haben. Wir können nicht nur jedem Appender eine individuelle Nachrichtenfilterstufe zuweisen, sondern auch Nachrichten nach Paket filtern! Aus diesem Grund müssen Sie beim Erstellen eines Loggers eine Klasse angeben (ich spreche von LoggerFactory.getLogger ).

"Zum Beispiel:"

Protokollierung an der Konsole und einer Datei
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

„Zeilen 6 und 15 – Wir legen für jeden Appender unsere eigene Filterstufe fest.“

„Zeilen 20–23 – Wir geben den Paketnamen und die Filterstufe für seine Nachrichten an. Log4j.logger ist ein Präfix: Der Paketname wird orange hervorgehoben.“

„Wirklich? Das kannst du sogar. Na ja, cool!“

„Übrigens sind weder log4j noch slf4j im JDK enthalten. Sie müssen sie separat herunterladen. Das können Sie hier tun . Aber es geht auch anders:“

Schritt 1. Importe zur Klasse hinzufügen:“

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Schritt 2. Setzen Sie den Cursor auf diese Zeilen und drücken Sie Alt+Enter in IntelliJ IDEA.“

" Schritt 3 : Wählen Sie den Menüpunkt „JAR-Datei im Web“ aus.

Schritt 4. Wählen Sie ‚slf4j-log4j13.jar‘“

Schritt 5. Geben Sie an, wo die Bibliothek (jar) heruntergeladen werden soll.“

Schritt 6. Verwenden Sie die Klassen, die Sie benötigen.“

„Whoa! Was war das für ein Tag. So viel Neues und so viel Cooles!“

„Hier ist ein weiterer guter Artikel zum Thema Protokollierung: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC

„Okay, das reicht. Entspannen Sie sich, Programmierer.“