SLF4J - Kurzanleitung
SLF4J steht für Sumsetzen Logging Facade für Java. Es bietet eine einfache Abstraktion aller Protokollierungsframeworks in Java. Auf diese Weise kann ein Benutzer mit einem der Protokollierungsframeworks wie Log4j, Logback und arbeitenJUL(java.util.logging) unter Verwendung einer einzelnen Abhängigkeit. Sie können zur Laufzeit / Bereitstellungszeit auf das erforderliche Protokollierungsframework migrieren.
Ceki Gülcü hat SLF4J als Alternative zum Commons-Logging-Framework von Jakarta entwickelt.
Vorteile von SLF4J
Im Folgenden sind die Vorteile von SLF4J aufgeführt:
Mit dem SLF4J-Framework können Sie zum Zeitpunkt der Bereitstellung auf das gewünschte Protokollierungsframework migrieren.
Slf4J bietet Bindungen zu allen gängigen Protokollierungsframeworks wie log4j, JUL, Simple Logging und NOP. Daher können Sie zum Zeitpunkt der Bereitstellung zu einem dieser gängigen Frameworks wechseln.
SLF4J unterstützt parametrisierte Protokollierungsnachrichten unabhängig von der von Ihnen verwendeten Bindung.
Da SLF4J das Anwendungs- und Protokollierungsframework entkoppelt, können Sie problemlos Anwendungen unabhängig von Protokollierungsframeworks schreiben. Sie müssen sich nicht um das Protokollierungsframework kümmern, das zum Schreiben einer Anwendung verwendet wird.
SLF4J bietet ein einfaches Java-Tool, das als Migrator bezeichnet wird. Mit diesem Tool können Sie vorhandene Projekte, die Protokollierungsrahmen verwenden, wie Jakarta Commons Logging (JCL) oder log4j oder Java.util.logging (JUL), auf SLF4J migrieren.
Das Anmelden bei der Programmierung bezieht sich auf das Aufzeichnen von Aktivitäten / Ereignissen. Normalerweise sollten sich die Anwendungsentwickler um die Protokollierung kümmern.
Um die Protokollierung zu vereinfachen, bietet Java verschiedene Frameworks - log4J, java.util.logging (JUL), winziges Protokoll, Logback usw.
Übersicht über das Protokollierungsframework
Ein Protokollierungsframework enthält normalerweise drei Elemente:
Logger
Erfasst die Nachricht zusammen mit den Metadaten.
Formatierer
Formatiert die vom Logger erfassten Nachrichten.
Handler
Der Handler oder Appender versendet die Nachrichten schließlich entweder durch Drucken auf der Konsole oder durch Speichern in der Datenbank oder durch Senden per E-Mail.
Einige Frameworks kombinieren die Logger- und Appender-Elemente, um die Vorgänge zu beschleunigen.
Logger-Objekt
Um eine Nachricht zu protokollieren, sendet die Anwendung ein Protokollierungsobjekt (manchmal zusammen mit den Ausnahmen, falls vorhanden) mit Name und Sicherheitsstufe.
Schweregrad
Die protokollierten Nachrichten haben verschiedene Ebenen. In der folgenden Tabelle sind die allgemeinen Protokollierungsstufen aufgeführt.
Sr.Nr. | Schweregrad & Beschreibung |
---|---|
1 | Fatal Schweres Problem, durch das die Anwendung beendet wird. |
2 | ERROR Laufzeitfehler. |
3 | WARNING In den meisten Fällen sind die Fehler auf die Verwendung veralteter APIs zurückzuführen. |
4 | INFO Ereignisse, die zur Laufzeit auftreten. |
5 | DEBUG Informationen zum Systemfluss. |
6 | TRACE Detailliertere Informationen zum Systemfluss. |
Was ist log4j?
log4j ist zuverlässig, schnell und flexibel logging framework (APIs) written in Java, die unter der Apache Software License vertrieben wird.
log4j kann zur Laufzeit über externe Konfigurationsdateien in hohem Maße konfiguriert werden. Es zeigt den Protokollierungsprozess in Bezug auf Prioritätsstufen an und bietet Mechanismen, um Protokollierungsinformationen an eine Vielzahl von Zielen wie eine Datenbank, eine Datei, eine Konsole, ein UNIX-Syslog usw. zu leiten (weitere Informationen zu log4j finden Sie in unserem Lernprogramm ).
Vergleich SLF4J und Log4j
Im Gegensatz zu log4j ist SLF4J (Sumsetzen Logging Facade für Java) ist keine Implementierung des Protokollierungsframeworks, sondern eine abstraction for all those logging frameworks in Java similar to log4J. Daher können Sie nicht beide vergleichen. Es ist jedoch immer schwierig, eine zwischen den beiden zu bevorzugen.
Wenn Sie die Wahl haben, ist die Protokollierungsabstraktion immer dem Protokollierungsframework vorzuziehen. Wenn Sie eine Protokollierungsabstraktion verwenden, insbesondere SLF4J, können Sie zu jedem Protokollierungsframework migrieren, das Sie zum Zeitpunkt der Bereitstellung benötigen, ohne sich für eine einzelne Abhängigkeit zu entscheiden.
Beachten Sie das folgende Diagramm, um ein besseres Verständnis zu erhalten.
In diesem Kapitel wird erläutert, wie Sie die SLF4J-Umgebung in der Eclipse-IDE festlegen. Stellen Sie vor der Installation sicher, dass Eclipse bereits auf Ihrem System installiert ist. Wenn nicht, laden Sie Eclipse herunter und installieren Sie es.
Weitere Informationen zu Eclipse finden Sie in unserem Eclipse-Tutorial
Schritt 1: Laden Sie die Abhängigkeits-JAR-Datei herunter
Öffnen Sie die offizielle Homepage der SLF4J-Website und rufen Sie die Download-Seite auf.
Laden Sie jetzt die neueste stabile Version von herunter slf4j-X.X.tar.gzoder slf4j-XXzip , je nach Betriebssystem (wenn Windows-ZIP-Datei oder Linux-Tar.gz-Datei).
Im heruntergeladenen Ordner finden Sie slf4j-api-XXjar . Dies ist die erforderliche Jar-Datei.
Schritt 2: Erstellen Sie ein Projekt und legen Sie den Erstellungspfad fest
Öffnen Sie Eclipse und erstellen Sie ein Beispielprojekt. Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie die OptionBuild Path → Configure Build Path… Wie nachfolgend dargestellt.
In dem Java Build Path Rahmen in der Libraries Klicken Sie auf die Registerkarte Add External JARs…
Wähle aus slf4j-api.x.x.jar Datei heruntergeladen und klicken Apply and Close.
SLF4J Bindungen
Zusätzlich zu slf4j-api.x.x.jar Datei, SLF4Jbietet mehrere andere Jar-Dateien wie unten gezeigt. Diese nennt manSLF4J bindings.
Wobei jede Bindung für das jeweilige Protokollierungsframework bestimmt ist.
In der folgenden Tabelle sind die SLF4J-Bindungen und ihre entsprechenden Frameworks aufgeführt.
Sr.Nr. | Jar-Datei & Protokollierungs-Framework |
---|---|
1 | slf4j-nop-x.x.jar Keine Operation, verwirft alle Protokollierungen. |
2 | slf4j-simple-x.x.jar Einfache Implementierung, bei der Nachrichten für Informationen und höher gedruckt werden und alle Ausgaben an System.err verbleiben. |
3 | slf4j-jcl-x.x.jar Jakarta Commons Logging Framework. |
4 | slf4j-jdk14-x.x.jar Java.util.logging Framework (JUL). |
5 | slf4j-log4j12-x.x.jar Log4J Rahmenarbeit. Darüber hinaus müssen Sie habenlog4j.jar. |
Damit SLF4J mit slf4l-api-xxjar zusammenarbeitet, müssen Sie die entsprechende Jar-Datei (Bindung) des gewünschten Logger-Frameworks in den Klassenpfad des Projekts einfügen (Build-Pfad festlegen).
Um von einem Framework zu einem anderen zu wechseln, müssen Sie die entsprechende Bindung ersetzen. Wenn keine Begrenzung gefunden wird, wird standardmäßig der Modus ohne Betrieb verwendet.
Pom.xml für SLF4J
Wenn Sie das Maven-Projekt erstellen, öffnen Sie das pom.xml Fügen Sie den folgenden Inhalt ein und aktualisieren Sie das Projekt.
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Sample</groupId>
<artifactId>Sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
</project>
In diesem Kapitel werden wir die Klassen und Methoden diskutieren, die wir in den folgenden Kapiteln dieses Tutorials verwenden werden.
Logger-Schnittstelle
Die Logger-Schnittstelle der org.slf4jPaket ist der Einstiegspunkt der SLF4J-API. Im Folgenden werden die wichtigen Methoden dieser Schnittstelle aufgelistet.
Sr.Nr. | Methoden und Beschreibung |
---|---|
1 | void debug(String msg) Diese Methode protokolliert eine Nachricht auf DEBUG-Ebene. |
2 | void error(String msg) Diese Methode protokolliert eine Nachricht auf ERROR-Ebene. |
3 | void info(String msg) Diese Methode protokolliert eine Nachricht auf INFO-Ebene. |
4 | void trace(String msg) Diese Methode protokolliert eine Nachricht auf TRACE-Ebene. |
5 | void warn(String msg) Diese Methode protokolliert eine Nachricht auf WARN-Ebene. |
LoggerFactory-Klasse
Die LoggerFactory-Klasse der org.slf4j package ist eine Dienstprogrammklasse, mit der Protokollierer für verschiedene Protokollierungs-APIs wie log4j, JUL, NOP und Simple Logger generiert werden.
Sr.Nr. | Methode und Beschreibung |
---|---|
1 | Logger getLogger(String name) Diese Methode akzeptiert einen Zeichenfolgenwert, der einen Namen darstellt, und gibt a zurück Logger Objekt mit dem angegebenen Namen. |
Profiler-Klasse
Diese Klasse gehört zum Paket org.slf4jDies wird zu Profilierungszwecken verwendet und ist als Profiler für arme Männer bekannt. Auf diese Weise kann der Programmierer die Zeit ermitteln, die für die Ausführung längerer Aufgaben benötigt wird.
Im Folgenden sind die wichtigen Methoden dieser Klasse aufgeführt.
Sr.Nr. | Methoden und Beschreibung |
---|---|
1 | void start(String name) Diese Methode startet eine neue Kinderstoppuhr (benannt) und stoppt die früheren Kinderstoppuhren (oder Zeitinstrumente). |
2 | TimeInstrument stop() Diese Methode stoppt die aktuelle untergeordnete Stoppuhr und die globale Stoppuhr und gibt das aktuelle Zeitinstrument zurück. |
3 | void setLogger(Logger logger) Diese Methode akzeptiert ein Logger-Objekt und ordnet den angegebenen Logger dem aktuellen Profiler zu. |
4 | void log() Protokolliert den Inhalt des aktuellen Zeitinstruments, das einem Logger zugeordnet ist. |
5 | void print() Druckt den Inhalt des aktuellen Zeitinstruments. |
In diesem Kapitel sehen wir ein einfaches grundlegendes Loggerprogramm mit SLF4J. Befolgen Sie die unten beschriebenen Schritte, um einen einfachen Logger zu schreiben.
Schritt 1 - Erstellen Sie ein Objekt der Schnittstelle slf4j.Logger
Seit der slf4j.Logger ist der Einstiegspunkt der SLF4J-API. Zuerst müssen Sie das Objekt abrufen / erstellen
Das getLogger() Methode der LoggerFactory Klasse akzeptiert einen Zeichenfolgenwert, der einen Namen darstellt, und gibt a zurück Logger Objekt mit dem angegebenen Namen.
Logger logger = LoggerFactory.getLogger("SampleLogger");
Schritt 2 - Protokollieren Sie die erforderliche Nachricht
Das info() Methode der slf4j.Logger Die Schnittstelle akzeptiert einen Zeichenfolgenwert, der die erforderliche Nachricht darstellt, und protokolliert ihn auf der Informationsebene.
logger.info("Hi This is my first SLF4J program");
Beispiel
Das folgende Programm zeigt, wie ein Beispiellogger mit SLF4J in Java geschrieben wird.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JExample {
public static void main(String[] args) {
//Creating the Logger object
Logger logger = LoggerFactory.getLogger("SampleLogger");
//Logging the information
logger.info("Hi This is my first SLF4J program");
}
}
Ausgabe
Wenn Sie das folgende Programm anfänglich ausführen, erhalten Sie anstelle der gewünschten Meldung die folgende Ausgabe.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further
details.
Da wir den Klassenpfad nicht auf eine Bindung festgelegt haben, die ein Protokollierungsframework darstellt, wie bereits in diesem Lernprogramm erwähnt, hat SLF4J standardmäßig eine Implementierung ohne Operation verwendet. Um die Nachricht anzuzeigen, müssen Sie die gewünschte Bindung in den Projektklassenpfad einfügen. Da wir Eclipse verwenden, setzen Siebuild path für die jeweilige JAR-Datei oder fügen Sie ihre Abhängigkeit in die Datei pom.xml ein.
Wenn wir beispielsweise JUL (Java.util.logging Framework) verwenden müssen, müssen wir den Erstellungspfad für die JAR-Datei festlegen slf4j-jdk14-x.x.jar. Und wenn wir das log4J-Protokollierungsframework verwenden möchten, müssen wir den Erstellungspfad festlegen oder Abhängigkeiten für die JAR-Dateien hinzufügenslf4j-log4j12-x.x.jar und log4j.jar.
Nach dem Hinzufügen der Bindung, die eines der Protokollierungsframeworks außer darstellt slf4j-nopx.x.jar Für das Projekt (Klassenpfad) erhalten Sie die folgende Ausgabe.
Dec 06, 2018 5:29:44 PM SLF4JExample main
INFO: Hi Welcome to Tutorialspoint
In diesem Kapitel werden die verschiedenen Fehlermeldungen oder Warnungen, die wir bei der Arbeit mit SLF4J erhalten, sowie die Ursachen / Bedeutungen dieser Meldungen erläutert.
Fehler beim Laden der Klasse "org.slf4j.impl.StaticLoggerBinder".
Dies ist eine Warnung, die ausgelöst wird, wenn im Klassenpfad keine SLF4J-Bindungen bereitgestellt werden.
Es folgt die vollständige Warnung -
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further
details.
Um dies zu beheben, müssen Sie eine der Protokollierungsframework-Bindungen hinzufügen. Dies wird in der erklärtHello world Kapitel dieses Tutorials.
Note - Dies tritt in Versionen von SLF4J auf, die zwischen 1.6.0 und 1.8.0-beta2 liegen.
Es wurden keine SLF4J-Anbieter gefunden
In slf4j-1.8.0-beta2 ist die obige Warnung klarer “No SLF4J providers were found”.
Es folgt die vollständige Warnung -
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
Classpath enthält SLF4J-Bindungen für slf4j-api-Versionen vor 1.8
Wenn Sie die SLF4J 1.8-Version verwenden und die Bindungen früherer Versionen im Klassenpfad haben, jedoch nicht die Bindungen 1.8, wird eine Warnung angezeigt (siehe unten).
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions prior to
1.8.
SLF4J: Ignoring binding found at
[jar:file:/C:/Users/Tutorialspoint/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-jdk14-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#ignoredBindings for an explanation.
NoClassDefFoundError: org / apache / commons / logging / LogFactory
Wenn Sie mit arbeiten slf4j-jcl und wenn du nur hast slf4j-jcl.jar In Ihrem Klassenpfad erhalten Sie eine Ausnahme wie die unten angegebene.
Exception in thread "main" java.lang.NoClassDefFoundError:
org/apache/commons/logging/LogFactory
at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:77)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.ClassNotFoundException:
org.apache.commons.logging.LogFactory
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more
Um dies zu beheben, müssen Sie hinzufügen commons-logging.jar zu deinem Klassenpfad.
Es wurde sowohl jcl-over-slf4j.jar als auch gebundenes slf4j-jcl.jar im Klassenpfad erkannt.
Die Bindung slf4j-jcl.jar leitet Aufrufe des slf4j-Loggers an JCL und den um jcl-over-slf4j.jarleitet Aufrufe des JCL-Loggers an slf4j weiter. Daher können Sie nicht beide im Klassenpfad Ihres Projekts haben. Wenn Sie dies tun, erhalten Sie eine Ausnahme wie die unten angegebene.
SLF4J: Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the class
path, preempting StackOverflowError.
SLF4J: See also http://www.slf4j.org/codes.html#jclDelegationLoop for more
details.
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:71)
at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:42)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.IllegalStateException: Detected both jcl-over-slf4j.jar
AND bound slf4j-jcl.jar on the class path, preempting StackOverflowError. See
also http://www.slf4j.org/codes.html#jclDelegationLoop for more details.
at org.slf4j.impl.JCLLoggerFactory.<clinit>(JCLLoggerFactory.java:54)
... 7 more
Um dies zu beheben, löschen Sie eine der JAR-Dateien.
Nicht übereinstimmende Loggernamen erkannt
Sie können ein Logger-Objekt erstellen, indem Sie -
Übergabe des Namens des zu erstellenden Loggers als Argument an die getLogger() Methode.
Übergeben einer Klasse als Argument an diese Methode.
Wenn Sie versuchen, das Logger-Factory-Objekt durch Übergeben einer Klasse als Argument zu erstellen, und wenn Sie die Systemeigenschaft festgelegt haben slf4j.detectLoggerNameMismatch zu true, dann der Name der Klasse, die Sie als Argument an die übergeben getLogger() Methode und die von Ihnen verwendete Klasse sollten identisch sein, andernfalls erhalten Sie die folgende Warnung:
„Erkennung einer Nichtübereinstimmung des Loggernamens festgestellt.
Betrachten Sie das folgende Beispiel.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JExample {
public static void main(String[] args) {
System.setProperty("slf4j.detectLoggerNameMismatch", "true");
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("Hi Welcome to Tutorilspoint");
}
}
Hier haben wir die Eigenschaft slf4j.detectLoggerNameMismatch auf true gesetzt. Der Name der Klasse, die wir verwendet haben, istSLF4JExample und der Klassenname, den wir an die Methode getLogger () übergeben haben, lautet Sample Da beide nicht gleich sind, erhalten wir die folgende Warnung.
SLF4J: Detected logger name mismatch. Given name: "Sample"; computed name:
"SLF4JExample".
SLF4J: See http://www.slf4j.org/codes.html#loggerNameMismatch for an
explanation
Dec 10, 2018 12:43:00 PM SLF4JExample main
INFO: Hi Welcome to Tutorilspoint
Note - Dies geschieht nach slf4j 1.7.9
Der Klassenpfad enthält mehrere SLF4J-Bindungen.
Sie sollten nur eine Bindung im Klassenpfad haben. Wenn Sie mehr als eine Bindung haben, erhalten Sie eine Warnung, in der die Bindungen und ihre Positionen aufgeführt sind.
Nehmen wir an, wir haben die Bindungen slf4j-jdk14.jar und slf4j-nop.jar Im Klassenpfad erhalten wir die folgende Warnung.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in
[jar:file:/C:/Users/Tutorialspoint/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-nop-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in
[jar:file:/C:/Users/Tutorialspoint/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-jdk14-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an
explanation.
SLF4J: Actual binding is of type [org.slf4j.helpers.NOPLoggerFactory]
Es wurde sowohl log4j-over-slf4j.jar als auch gebundenes slf4j-log4j12.jar im Klassenpfad erkannt
Um die log4j-Logger-Aufrufe an slf4j umzuleiten, müssen Sie verwenden log4j-over-slf4j.jar Bindung und wenn Sie slf4j-Aufrufe an log4j umleiten möchten, müssen Sie verwenden slf4j-log4j12.jar Bindung.
Daher können Sie nicht beide im Klassenpfad haben. Wenn Sie dies tun, erhalten Sie die folgende Ausnahme.
SLF4J: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the
class path, preempting StackOverflowError.
SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more
details.
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72)
at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar
AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError.
See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
Wie bereits in diesem Lernprogramm erläutert, bietet SLF4J Unterstützung für parametrisierte Protokollnachrichten.
Sie können Parameter in den Nachrichten verwenden und später in derselben Anweisung Werte an diese übergeben.
Syntax
Wie unten gezeigt, müssen Sie Platzhalter ({}) in der Nachricht (Zeichenfolge) verwenden, wo immer Sie möchten, und später können Sie den Wert für Platzhalter in übergeben object Formular, Nachricht und Wert durch Komma trennen.
Integer age;
Logger.info("At the age of {} ramu got his first job", age);
Beispiel
Das folgende Beispiel zeigt die parametrisierte Protokollierung (mit einem einzelnen Parameter) mit SLF4J.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(PlaceHolders.class);
Integer age = 23;
//Logging the information
logger.info("At the age of {} ramu got his first job", age);
}
}
Ausgabe
Bei der Ausführung generiert das obige Programm die folgende Ausgabe:
Dec 10, 2018 3:25:45 PM PlaceHolders main
INFO: At the age of 23 Ramu got his first job
Vorteil der parametrisierten Protokollierung
Wenn wir in Java Werte in einer Anweisung drucken müssen, verwenden wir den Verkettungsoperator als -
System.out.println("At the age of "+23+" ramu got his first job");
Dies beinhaltet die Umwandlung des ganzzahligen Werts 23 in eine Zeichenfolge und die Verkettung dieses Werts mit den ihn umgebenden Zeichenfolgen.
Wenn es sich um eine Protokollierungsanweisung handelt und diese bestimmte Protokollierungsstufe Ihrer Anweisung deaktiviert ist, ist diese Berechnung nicht von Nutzen.
In solchen Fällen können Sie die parametrisierte Protokollierung verwenden. In diesem Format bestätigt SLF4J zunächst, ob die Protokollierung für eine bestimmte Ebene aktiviert ist. Wenn ja, werden die Platzhalter in den Nachrichten durch die entsprechenden Werte ersetzt.
Zum Beispiel, wenn wir eine Aussage als haben
Integer age;
Logger.debug("At the age of {} ramu got his first job", age);
Nur wenn das Debuggen aktiviert ist, konvertiert SLF4J das Alter in eine Ganzzahl und verkettet es mit den Zeichenfolgen. Andernfalls wird nichts unternommen. Dies verursacht die Kosten für Parameterkonstruktionen, wenn die Protokollierungsstufe deaktiviert ist.
Variante mit zwei Argumenten
Sie können in einer Nachricht auch zwei Parameter als - verwenden
logger.info("Old weight is {}. new weight is {}.", oldWeight, newWeight);
Beispiel
Das folgende Beispiel zeigt die Verwendung von zwei Platzhaltern bei der parametrisierten Protokollierung.
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
Integer oldWeight;
Integer newWeight;
Scanner sc = new Scanner(System.in);
System.out.println("Enter old weight:");
oldWeight = sc.nextInt();
System.out.println("Enter new weight:");
newWeight = sc.nextInt();
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("Old weight is {}. new weight is {}.", oldWeight, newWeight);
//Logging the information
logger.info("After the program weight reduced is: "+(oldWeight-newWeight));
}
}
Ausgabe
Bei der Ausführung generiert das obige Programm die folgende Ausgabe.
Enter old weight:
85
Enter new weight:
74
Dec 10, 2018 4:12:31 PM PlaceHolders main
INFO: Old weight is 85. new weight is 74.
Dec 10, 2018 4:12:31 PM PlaceHolders main
INFO: After the program weight reduced is: 11
Variante mit mehreren Argumenten
Sie können auch mehr als zwei Platzhalter verwenden, wie im folgenden Beispiel gezeigt -
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
Integer age = 24;
String designation = "Software Engineer";
String company = "Infosys";
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("At the age of {} ramu got his first job as a {} at {}", age, designation, company);
}
}
Ausgabe
Bei der Ausführung generiert das obige Programm die folgende Ausgabe:
Dec 10, 2018 4:23:52 PM PlaceHolders main
INFO: At the age of 24 ramu got his first job as a Software Engineer at Infosys
Wenn Sie ein Projekt in Jakarta Commons Logging (JCL) oder log4j oder java.util.logging (JUL) haben und diese Projekte in SLF4J konvertieren möchten, können Sie dies mit dem in der SLF4J-Distribution bereitgestellten Migrator-Tool tun.
Ausführen von SLF4J Migrator
SLF4J ist eine einfache JAR-Datei (slf4j-migrator.jar), die Sie mit dem Befehl java –jar ausführen können.
Um es auszuführen, durchsuchen Sie an der Eingabeaufforderung das Verzeichnis, in dem Sie diese JAR-Datei haben, und führen Sie den folgenden Befehl aus.
java -jar slf4j-migrator-1.8.0-beta2.jar
Starting SLF4J Migrator
Dadurch wird der Migrator gestartet und Sie können eine eigenständige Java-Anwendung als - sehen
Wie im Fenster angegeben, müssen Sie den gewünschten Migrationstyp überprüfen, das Projektverzeichnis auswählen und auf die Schaltfläche Projekt nach SLF4J migrieren klicken.
Dieses Tool wechselt zu den von Ihnen bereitgestellten Quelldateien und führt einfache Änderungen durch, z. B. das Ändern der Importzeilen und Protokollierungsdeklarationen vom aktuellen Protokollierungsframework in SLF4j.
Beispiel
Nehmen wir zum Beispiel an, wir haben eine Stichprobe log4j(2) Projekt in Eclipse mit einer einzelnen Datei wie folgt -
import org.apache.log4j.Logger;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class Sample {
/* Get actual class name to be printed on */
static Logger log = Logger.getLogger(Sample.class.getName());
public static void main(String[] args)throws IOException,SQLException {
log.debug("Hello this is a debug message");
log.info("Hello this is an info message");
}
}
So migrieren Sie das Beispiel log4j(2) Projekt zu slf4j, müssen wir das Optionsfeld überprüfen from log4j to slf4j und wählen Sie das Verzeichnis des Projekts und klicken Sie auf Exit migrieren.
Der Migrator hat den obigen Code wie folgt geändert. Hier, wenn Sie beobachten, wurden die Import- und Logger-Anweisungen geändert.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class Sample {
static Logger log = LoggerFactory.getLogger(Sample.class.getName());
public static void main(String[] args)throws IOException,SQLException {
log.debug("Hello this is a debug message");
log.info("Hello this is an info message");
}
}
Da hast du schon log4j.jar In Ihrem Projekt müssen Sie hinzufügen slf4j-api.jar und slf4jlog12.jar Dateien an das Projekt, um es auszuführen.
Einschränkungen von SLF4JMigrator
Im Folgenden sind die Einschränkungen des SLF4J-Migrators aufgeführt.
Migrator ändert keine Build-Skripte wie ant, maven und ivy, die Sie selbst ausführen müssen.
Migrator unterstützt keine anderen Nachrichten als den String-Typ.
Migrator unterstützt die FATAL-Ebene nicht.
Während der Arbeit mit log4j migriert der Migrator keine Aufrufe an PropertyConfigurator oder DomConfigurator.
SLF4J Distribution bietet slf4j-ext.jar Diese enthält APIs für die Funktionen wie Profilerstellung, Erweiterte Protokollierung, Ereignisprotokollierung und Protokollierung mit Java Agent.
Profilerstellung
Manchmal möchte der Programmierer einige Attribute wie die Verwendung des Speichers, die Zeitkomplexität oder die Verwendung bestimmter Anweisungen zu den Programmen messen, um die tatsächliche Leistungsfähigkeit dieses Programms zu messen. Eine solche Messung des Programms wird als Profiling bezeichnet. Die Profilerstellung verwendet eine dynamische Programmanalyse, um solche Messungen durchzuführen.
SLF4J bietet eine Klasse mit dem Namen Profiler in dem org.slf4j.profilerPaket für Profilierungszwecke. Dies ist als Profiler des armen Mannes bekannt. Auf diese Weise kann der Programmierer die Zeit ermitteln, die für die Ausführung längerer Aufgaben benötigt wird.
Profilerstellung mit der Profiler-Klasse
Der Profiler enthält Stoppuhren und untergeordnete Stoppuhren, und wir können diese mit den von der Profiler-Klasse bereitgestellten Methoden starten und stoppen.
Führen Sie die folgenden Schritte aus, um mit der Profilerstellung mithilfe der Profiler-Klasse fortzufahren.
Schritt 1 - Instanziieren Sie die Profiler-Klasse
Instanziieren Sie die Profiler-Klasse, indem Sie einen String-Wert übergeben, der den Namen des Profilers darstellt. Wenn wir eine Profiler-Klasse instanziieren, wird eine globale Stoppuhr gestartet.
//Creating a profiler
Profiler profiler = new Profiler("Sample");
Schritt 2 - Starten Sie eine Kinderstoppuhr
Wenn wir das aufrufen start() Methode startet es eine neue untergeordnete Stoppuhr (benannt) und stoppt die früheren untergeordneten Stoppuhren (oder Zeitinstrumente).
Rufen Sie die start() Methode der Profiler Klasse durch Übergabe eines String-Werts, der den Namen der zu erstellenden untergeordneten Stoppuhr darstellt.
//Starting a child stopwatch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
Nach dem Erstellen dieser Stoppuhren können Sie Ihre Aufgaben ausführen oder die Methoden aufrufen, mit denen Ihre Aufgaben ausgeführt werden.
Schritt 3: Starten Sie eine weitere Kinderstoppuhr (wenn Sie möchten)
Erstellen Sie bei Bedarf eine weitere Stoppuhr mit der start()Methode und führen Sie die erforderlichen Aufgaben. Wenn Sie dies tun, wird eine neue Stoppuhr gestartet und die vorherige gestoppt (dh Aufgabe 1).
//Starting another child stopwatch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
Schritt 4: Stoppen Sie die Uhren
Wenn wir das aufrufen stop() Methode stoppt es die letzte untergeordnete Stoppuhr und die globale Stoppuhr und gibt das aktuelle Zeitinstrument zurück.
// Stopping the current child stopwatch and the global stopwatch.
TimeInstrument tm = profiler.stop();
Schritt 5: Drucken Sie den Inhalt des Zeitinstruments.
Drucken Sie den Inhalt des aktuellen Zeitinstruments mit der print() Methode.
//printing the contents of the time instrument
tm.print();
Beispiel
Das folgende Beispiel zeigt die Profilerstellung mit der Profiler-Klasse von SLF4J. Hier haben wir zwei Beispielaufgaben ausgeführt: Drucken der Quadratsumme der Zahlen von 1 bis 10000 und Drucken der Summe der Zahlen von 1 bis 10000. Wir versuchen, die für diese beiden Aufgaben benötigte Zeit zu ermitteln.
import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;
public class ProfilerExample {
public void demoMethod1(){
double sum = 0;
for(int i=0; i< 1000; i++){
sum = sum+(Math.pow(i, 2));
}
System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
}
public void demoMethod2(){
int sum = 0;
for(int i=0; i< 10000; i++){
sum = sum+i;
}
System.out.println("Sum of the numbers from 1 to 10000: "+sum);
}
public static void main(String[] args) {
ProfilerExample obj = new ProfilerExample();
//Creating a profiler
Profiler profiler = new Profiler("Sample");
//Starting a child stop watch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
//Starting another child stop watch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
//Stopping the current child watch and the global watch.
TimeInstrument tm = profiler.stop();
//printing the contents of the time instrument
tm.print();
}
}
Ausgabe
Bei der Ausführung generiert das obige Programm die folgende Ausgabe:
Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000
+ Profiler [BASIC]
|-- elapsed time [Task 1] 2291.827 microseconds.
|-- elapsed time [Task 2] 225.802 microseconds.
|-- Total [BASIC] 3221.598 microseconds.
Protokollierung der Profiler-Informationen
Anstatt das Ergebnis eines Profilers zu drucken, um diese Informationen zu protokollieren, müssen Sie -
Erstellen Sie einen Logger mit dem LoggerFactory Klasse.
Erstellen Sie einen Profiler, indem Sie die Profiler-Klasse instanziieren.
Verknüpfen Sie den Logger mit dem Profiler, indem Sie das erstellte Logger-Objekt an das übergeben setLogger() Methode der Profiler Klasse.
Anstatt zu drucken, protokollieren Sie schließlich die Informationen des Profilers mit dem log() Methode.
Beispiel
Im folgenden Beispiel versuchen wir im Gegensatz zum vorherigen (anstatt zu drucken), den Inhalt des Zeitinstruments zu protokollieren.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;
public class ProfilerExample_logger {
public void demoMethod1(){
double sum = 0;
for(int i=0; i< 1000; i++){
sum = sum+(Math.pow(i, 2));
}
System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
}
public void demoMethod2(){
int sum = 0;
for(int i=0; i< 10000; i++){
sum = sum+i;
}
System.out.println("Sum of the numbers from 1 to 10000: "+sum);
}
public static void main(String[] args) {
ProfilerExample_logger obj = new ProfilerExample_logger();
//Creating a logger
Logger logger = LoggerFactory.getLogger(ProfilerExample_logger.class);
//Creating a profiler
Profiler profiler = new Profiler("Sample");
//Adding logger to the profiler
profiler.setLogger(logger);
//Starting a child stop watch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
//Starting another child stop watch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
//Stopping the current child watch and the global watch.
TimeInstrument tm = profiler.stop();
//Logging the contents of the time instrument
tm.log();
}
}
Ausgabe
Bei der Ausführung generiert das obige Programm die folgende Ausgabe.
Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000