JavaRush /Java-Blog /Random-DE /Warum ist eine Protokollierung erforderlich?

Warum ist eine Protokollierung erforderlich?

Veröffentlicht in der Gruppe Random-DE
Hallo! Beim Schreiben von Vorträgen achte ich besonders darauf, ob ein bestimmtes Thema unbedingt in der Praxis zum Einsatz kommt. Warum brauchen Sie eine Protokollierung? - 1 Also, ACHTUNG! Das Thema, das wir heute ansprechen werden, wird Ihnen vom ersten Arbeitstag an bei all Ihren Projekten auf jeden Fall von Nutzen sein. Wir werden über die Protokollierung sprechen. Dieses Thema ist überhaupt nicht schwierig (ich würde sogar sagen einfach). Aber bei deinem ersten Job wird es schon so viel Stress geben, dass du dich noch mit den offensichtlichen Dingen auseinandersetzen musst, deshalb ist es besser, das jetzt gründlich zu klären :) Also, lasst uns anfangen. Was ist Protokollierung? Bei der Protokollierung werden irgendwo Daten über den Betrieb eines Programms aufgezeichnet. Der Ort, an dem diese Daten geschrieben werden, wird „ Protokoll “ genannt . Es stellen sich gleich zwei Fragen: Wo und welche Daten werden erfasst? Beginnen wir mit „wo“. Sie können Programmbetriebsdaten an vielen verschiedenen Orten aufzeichnen. Während Ihres Studiums geben Sie beispielsweise häufig Daten über aus System.out.println(). Das ist echte Protokollierung, wenn auch die einfachste. Für den Kunden oder das Produktsupport-Team ist das natürlich nicht sehr praktisch: Sie möchten die IDE natürlich nicht installieren und die Konsole überwachen :) Es gibt auch ein bekannteres Format zum Aufzeichnen von Informationen – in einer Textdatei. Auf diese Weise ist es für die Leute viel einfacher, sie zu lesen, und auf jeden Fall ist es viel einfacher, sie aufzubewahren! Nun die zweite Frage: Welche Daten über den Betrieb des Programms sollen im Protokoll aufgezeichnet werden? Aber hier hängt alles von Ihnen ab! Das Java-Protokollierungssystem ist sehr flexibel. Sie können es so konfigurieren, dass der gesamte Fortschritt Ihres Programms protokolliert wird. Das ist einerseits gut. Aber stellen Sie sich andererseits vor, welche Größe Facebook- oder Twitter-Protokolle erreichen können, wenn alles dort geschrieben wird. Solche großen Unternehmen sind wahrscheinlich in der Lage, selbst diese Menge an Informationen zu speichern. Aber stellen Sie sich vor, wie schwierig es wäre, in Protokollen mit 500 Gigabyte Text nach Informationen zu einem kritischen Fehler zu suchen? Es ist noch schlimmer als eine Nadel im Heuhaufen. Daher kann die Protokollierung in Java so konfiguriert werden, dass nur Fehlerdaten in das Protokoll (Log) geschrieben werden. Oder auch nur über kritische Fehler! Allerdings ist die Aussage „Anmelden in Java“ nicht ganz richtig. Tatsache ist, dass der Bedarf an Protokollierung bei Programmierern entstand, bevor diese Funktionalität zur Sprache hinzugefügt wurde. Und als Java seine eigene Protokollierungsbibliothek hatte, nutzte bereits jeder die log4j-Bibliothek. Die Entstehungsgeschichte der Protokollierung in Java ist tatsächlich sehr lang und informativ. Sie können diesen Beitrag in Ruhe auf Habré lesen . Kurz gesagt, Java verfügt über eine eigene Protokollierungsbibliothek, aber fast niemand verwendet sie :) Später, als mehrere verschiedene Protokollierungsbibliotheken auftauchten und alle Programmierer begannen, unterschiedliche zu verwenden, trat ein Kompatibilitätsproblem auf. Um zu verhindern, dass Menschen dasselbe tun und ein Dutzend verschiedener Bibliotheken mit unterschiedlichen Schnittstellen verwenden, wurde das Abstraktionsframework slf4j erstellt(„Service-Logging-Fassade für Java“). Dies wird als Abstraktion bezeichnet, denn obwohl Sie SLF4J-Klassen verwenden und deren Methoden aufrufen, laufen unter der Haube alle vorherigen Protokollierungsframeworks: log4j, Standard java.util.logging und andere. Wenn Sie derzeit eine bestimmte Funktion von log4j benötigen, die andere Bibliotheken nicht haben, Sie das Projekt aber nicht strikt mit dieser bestimmten Bibliothek verknüpfen möchten, verwenden Sie einfach slf4j. Und sie wird die log4j-Methoden bereits „ziehen“. Wenn Sie Ihre Meinung ändern und entscheiden, dass Sie die log4j-Funktionen nicht mehr benötigen, müssen Sie lediglich den „Wrapper“ (d. h. slf4j) neu konfigurieren, um eine andere Bibliothek zu verwenden. Ihr Code wird nicht aufhören zu funktionieren, da Sie darin Methoden von slf4j und nicht einer bestimmten Bibliothek aufrufen. Ein kleiner Exkurs. Damit die folgenden Beispiele funktionieren, müssen Sie die slf4j-Bibliothek hier und die log4j-Bibliothek hier herunterladen . Als nächstes müssen wir das Archiv entpacken und die benötigten JAR-Dateien über Intellij IDEA zum Klassenpfad hinzufügen. Menüpunkte: Datei -> Projektstruktur -> Bibliotheken Wählen Sie die erforderlichen JAR-Dateien aus und fügen Sie sie dem Projekt hinzu (in den von uns heruntergeladenen Archiven befinden sich viele JAR-Dateien, sehen Sie sich die benötigten JAR-Dateien auf den Bildern an). Warum brauchen Sie eine Protokollierung - 2Warum brauchen Sie eine Protokollierung - 3Hinweis: Für diese gilt diese Anleitung Studierende, die nicht wissen, wie man Maven verwendet. Wenn Sie wissen, wie man es verwendet, ist es besser, damit anzufangen: Normalerweise ist es viel einfacher. Wenn Sie Maven verwenden , fügen Sie diese Abhängigkeit hinzu:
<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.14.0</version>
</dependency>
Großartig, wir haben die Einstellungen geklärt :) Schauen wir uns an, wie slf4j funktioniert. Wie können wir sicherstellen, dass der Fortschritt des Programms irgendwo aufgezeichnet wird? Dazu benötigen wir zwei Dinge – einen Logger und einen Appender . Beginnen wir mit dem ersten. Ein Logger ist ein Objekt, das die Aufzeichnung vollständig verwaltet . Das Erstellen eines Loggers ist sehr einfach: Es erfolgt mit einer statischen Methode – LoggerFactory.getLogger(). Als Parameter für die Methode müssen Sie eine Klasse übergeben, deren Arbeit protokolliert wird. Lassen Sie uns unseren Code ausführen:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Test log record!!!");
       LOGGER.error("В программе возникла ошибка!");
   }
}
Konsolenausgabe: ERROR StatusLogger Keine Log4j 2-Konfigurationsdatei gefunden. Verwendung der Standardkonfiguration (Protokollierung nur von Fehlern in der Konsole) oder vom Benutzer programmgesteuert bereitgestellter Konfigurationen. Legen Sie die Systemeigenschaft „log4j2.debug“ fest, um die interne Initialisierungsprotokollierung von Log4j 2 anzuzeigen. Siehe https://logging.apache.org/log4j/2.x/manual/configuration.html für Anweisungen zur Konfiguration von Log4j 2 15:49:08.907 [main] ERROR MyTestClass – Im Programm ist ein Fehler aufgetreten! Was sehen wir hier? Zuerst sehen wir eine Fehlermeldung. Es erschien, weil uns derzeit die notwendigen Einstellungen fehlen. Daher kann unser Logger jetzt nur noch Fehlermeldungen (ERROR) und nur auf der Konsole ausgeben. Die Methode logger.info()wurde nicht ausgeführt. Aber logger.error()es hat funktioniert! Die Konsole zeigt das aktuelle Datum, die Methode, bei der der Fehler aufgetreten ist ( main), das Wort ERROR und unsere Nachricht! ERROR ist die Protokollierungsstufe. Wenn ein Protokolleintrag mit dem Wort ERROR gekennzeichnet ist, bedeutet dies im Allgemeinen, dass an dieser Stelle im Programm ein Fehler aufgetreten ist. Wenn ein Eintrag mit dem Wort INFO gekennzeichnet ist, bedeutet dies, dass es sich lediglich um aktuelle Informationen über den normalen Betrieb des Programms handelt. Die SLF4J-Bibliothek verfügt über zahlreiche verschiedene Protokollierungsstufen, mit denen Sie die Protokollierung flexibel konfigurieren können. Sie sind sehr einfach zu verwalten: Die gesamte erforderliche Logik ist bereits in der Klasse enthalten Logger. Sie müssen lediglich die erforderlichen Methoden aufrufen. Wenn Sie eine regelmäßige Nachricht posten möchten, rufen Sie an logger.info(). Fehlermeldung - logger.error(). Eine Warnung anzeigen – logger.warn() Lassen Sie uns nun über den Appender sprechen . Der Appender ist der Ort, an dem Ihre Daten ankommen. Man könnte sagen, das Gegenteil einer Datenquelle ist „Punkt B“. Standardmäßig werden Daten an die Konsole ausgegeben. Bitte beachten Sie, dass wir im vorherigen Beispiel nichts konfigurieren mussten: Der Text erschien in der Konsole selbst, aber der Logger aus der log4j-Bibliothek kann nur Meldungen der Ebene ERROR an die Konsole ausgeben. Für Benutzer ist es offensichtlich bequemer, Protokolle aus einer Textdatei zu lesen und Protokolle in denselben Dateien zu speichern. Um das Standardverhalten des Loggers zu ändern, müssen wir unseren Datei-Appender konfigurieren . Zunächst müssen Sie eine log4j.xml- Datei direkt im src-Ordner oder im Ressourcenordner, wenn Sie Maven verwenden, oder im Ressourcenordner, falls Sie Maven verwenden, erstellen. Sie kennen das XML-Format bereits, wir hatten kürzlich einen Vortrag darüber :) Dies wird sein Inhalt sein:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
   <Appenders>
       <File name="MyFileAppender" fileName="C:\Users\Username\Desktop\testlog.txt" immediateFlush="false" append="false">
           <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </File>
   </Appenders>
   <Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
   </Loggers>
</Configuration>
Es sieht nicht besonders kompliziert aus :) Aber gehen wir trotzdem den Inhalt durch.
<Configuration status="INFO">
Dies ist der sogenannte Statuslogger. Es hat nichts mit unserem Logger zu tun und wird intern von log4j verwendet. Sie können status=“TRACE“ anstelle von status=“INFO“ festlegen und alle Informationen über die internen Abläufe von log4j werden an die Konsole ausgegeben (status-logger gibt Daten an die Konsole aus, auch wenn unser Appender für das Programm eine Datei ist -basierend). Wir brauchen das jetzt nicht, also lassen wir alles so, wie es ist.
<Appenders>
   <File name="MyFileAppender" fileName="C:\Users\Евгений\Desktop\testlog.txt" append="true">
       <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
   </File>
</Appenders>
Hier erstellen wir unseren Appender. Das Tag <File>gibt an, dass es sich um eine Datei handelt. name="MyFileAppender"- der Name unseres Appenders. fileName="C:\Users\Username\Desktop\testlog.txt"— Pfad zur Protokolldatei, in die alle Daten geschrieben werden. append="true"— ob es notwendig ist, zusätzliche Daten an das Ende der Datei zu schreiben. In unserem Fall wird dies der Fall sein. Wenn auf false gesetzt , werden die alten Protokollinhalte bei jedem erneuten Start des Programms gelöscht. <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>- Dies sind Formatierungseinstellungen. Hier können wir reguläre Ausdrücke verwenden, um das Format des Textes in unserem Protokoll anzupassen.
<Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
</Loggers>
Hier legen wir den Logging-Level (Root-Level) fest. Wir haben die INFO-Ebene festgelegt: Das heißt, alle Nachrichten mit einer höheren Ebene als INFO (gemäß der oben betrachteten Tabelle) werden nicht in das Protokoll aufgenommen. Wir werden drei Meldungen in unserem Programm haben: eine INFO, eine WARN und eine ERROR. Mit der aktuellen Konfiguration werden alle 3 Meldungen in das Protokoll geschrieben. Wenn Sie die Root-Ebene auf ERROR ändern, wird nur die letzte Nachricht von LOGGER.error() protokolliert. Außerdem wird hier ein Link zum Appender platziert. Um einen solchen Link zu erstellen, müssen Sie <Root>ein Tag innerhalb des Tags erstellen <ApprenderRef>und ihm den Parameter hinzufügen ref=”Name твоего аппендера”. Den Namen des Appenders haben wir hier erstellt, falls Sie es vergessen haben: <File name="MyFileAppender" Und hier ist der Code unseres Programms!
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Начало работы программы!!!");

       try {
           LOGGER.warn("Внимание! Программа пытается разделить одно число на другое");
           System.out.println(12/0);
       } catch (ArithmeticException x) {

           LOGGER.error("Ошибка! Произошло деление на ноль!");
       }
   }
}
Natürlich ist es etwas schief (RuntimeException abzufangen ist eine mittelmäßige Idee), aber für unsere Zwecke ist es perfekt :) Lassen Sie uns unsere Methode main()viermal hintereinander ausführen und uns unsere testlog.txt-Datei ansehen. Es ist nicht erforderlich, es im Voraus zu erstellen: Die Bibliothek erledigt dies automatisch. Alles hat funktioniert! :) Jetzt haben Sie einen konfigurierten Logger. Sie können mit einigen Programmen, die Sie zuvor geschrieben haben, herumspielen, allen Methoden Logger-Aufrufe hinzufügen und sich das resultierende Protokoll ansehen :) Als zusätzliche Lektüre empfehle ich diesen Artikel wärmstens . Dort wird das Thema Protokollierung ausführlich behandelt und es wird nicht einfach sein, es am Stück zu lesen. Aber es enthält viele nützliche Zusatzinformationen. Sie erfahren beispielsweise, wie Sie einen Logger so konfigurieren, dass er eine neue Textdatei erstellt, wenn unsere testlog.txt-Datei eine bestimmte Größe erreicht :) Und das ist das Ende unserer Lektion! Heute haben Sie etwas über ein sehr wichtiges Thema gelernt, und dieses Wissen wird Ihnen bei Ihrer zukünftigen Arbeit auf jeden Fall nützlich sein. Wir sehen uns wieder! :) :)
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION