Es gibt eine Geschichte und eine Lösung für die Protokollausgabe.
In Logback können die Informationen des "Protokollierungsanforderungsgenerators" in die Protokollausgabe aufgenommen werden, indem der folgende Konvertierungsspezifizierer im Musterlayout [^ warning-1] angegeben wird.
Konvertierungsspezifizierer(alias) | Inhalt ausgeben |
---|---|
C (class) | Name der Anruferklasse(FQCN) |
M (method) | Name der Aufrufermethode |
F (file) | Name der Quellcodedatei |
L (line) | Zeilennummer in der Quellcodedatei |
caller[^1] | Standortinformationen des Anrufers |
[^ warning-1] :: warning: Das Abrufen der "Quelle der Protokollierungsanforderung" ist ein kostspieliger Prozess und verlangsamt die Ausführung. Verwenden wir es nur in der Entwicklungsumgebung usw. [^ 1]: Aufgrund des speziellen Ausgabeinhalts wird dieser Artikel nicht behandelt.
In diesem Artikel werden die folgenden Einstellungen als Beispiel für die Protokollausgabe verwendet. Beachten Sie den Inhalt des Elements "pattern". Mit dieser Einstellung können Sie den Klassennamen, den Dateinamen usw. in das Protokoll ausgeben. Das Debuggen schreitet voran.
logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[[%class.%method\(%file:%line\)]] %logger{0} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Beispiel für die Protokollausgabe
[[com.example.demo.DemoLogApplication.main(DemoLogApplication.java:16)]] DemoLogApplication - hello
Einzelheiten zu den Konvertierungsspezifizierern finden Sie im Handbuch.
Aus verschiedenen Gründen können Sie Ihren eigenen Logger definieren, ohne den Logger von SLF4J direkt zu verwenden. Wenn Sie zu diesem Zeitpunkt einfach die Verarbeitung auf den SLF4J-Logger (sogenannter Wrapper) übertragen, sind alle "Protokollierungsanforderungsgeneratoren" Ihr eigener Logger.
MyWrongLogger.java
package com.example.demo;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
public class MyWrongLogger {
//Logger von SLF4J übertragen werden
private final org.slf4j.Logger logger;
//Der Konstruktor ist privat
private MyWrongLogger(org.slf4j.Logger logger) {
this.logger = logger;
}
//Fabrikmethode
public static final MyWrongLogger getLogger(Class<?> clazz) {
org.slf4j.Logger logger = LoggerFactory.getLogger(clazz);
return new MyWrongLogger(logger);
}
//Unten Delegation an Logger
public boolean isTraceEnabled() {
return logger.isTraceEnabled();
}
public void trace(String msg) {
logger.trace(msg);
}
// (Folgendes wird weggelassen)
}
DemoLogApplication.java
package com.example.demo;
public class DemoLogApplication {
private static final MyWrongLogger WRONG_LOGGER = MyWrongLogger.getLogger(DemoLogApplication.class);
public static void main(String[] args) {
WRONG_LOGGER.info("hello");
WRONG_LOGGER.info("hello {}", "xxx");
WRONG_LOGGER.info("exception", new Exception("test"));
WRONG_LOGGER.info("{} {} {} exception", 1, 2, 3, new Exception("test"));
}
}
Beispiel für die Protokollausgabe("Generator der Protokollierungsanforderung" wurde zu MyWrongLogger)
[[com.example.demo.MyWrongLogger.info(MyWrongLogger.java:122)]] DemoLogApplication - hello
[[com.example.demo.MyWrongLogger.info(MyWrongLogger.java:126)]] DemoLogApplication - hello xxx
[[com.example.demo.MyWrongLogger.info(MyWrongLogger.java:138)]] DemoLogApplication - exception
java.lang.Exception: test
at com.example.demo.DemoLogApplication.main(DemoLogApplication.java:11)
[[com.example.demo.MyWrongLogger.info(MyWrongLogger.java:134)]] DemoLogApplication - 1 2 3 exception
java.lang.Exception: test
at com.example.demo.DemoLogApplication.main(DemoLogApplication.java:12)
Sicherlich ist es "MyWrongLogger", das die Logger-Methode aufruft ... Hin und wieder gibt es solche unglücklichen Protokolle.
Sie können dieses Problem mit SLF4Js LocationAwareLogger
[^ FQCN-1] lösen.
Sie können FQCN in der log
-Methode von LocationAwareLogger
angeben.
java:org.slf4j.spi.LocationAwareLogger
public void log(Marker marker, String fqcn, int level, String message, Object[] argArray, Throwable t);
Logbacks Logger
[^ FQCN-2] implementiert LocationAwareLogger
.
Mit anderen Worten, wenn Sie Logback verwenden, um die Protokollausgabe zu implementieren, können Sie den von der "LoggerFactory" erhaltenen "Logger" [^ FQCN-3] in den "LocationAwareLogger" umwandeln.
Das Folgende ist ein Beispiel für die Verwendung von LocationAwareLogger
.
MyLocationAwareLogger.java
package com.example.demo;
import static org.slf4j.spi.LocationAwareLogger.*;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
public class MyLocationAwareLogger {
// Marker(Diesmal nicht verwendet)
private static final Marker MARKER = null;
//FQCN dieser Klasse
private static final String FQCN = MyLocationAwareLogger.class.getName();
//Standortbewusster Logger des zu übertragenden SLF4J
private final org.slf4j.spi.LocationAwareLogger logger;
//Der Konstruktor ist privat
private MyLocationAwareLogger(org.slf4j.spi.LocationAwareLogger logger) {
this.logger = logger;
}
//Fabrikmethode
public static MyLocationAwareLogger getLogger(Class<?> clazz) {
org.slf4j.spi.LocationAwareLogger logger = (org.slf4j.spi.LocationAwareLogger) LoggerFactory.getLogger(clazz);
return new MyLocationAwareLogger(logger);
}
//<<< isXxxEnabled >>>
public boolean isTraceEnabled() { return logger.isTraceEnabled(); }
public boolean isDebugEnabled() { return logger.isDebugEnabled(); }
public boolean isInfoEnabled () { return logger.isInfoEnabled (); }
public boolean isWarnEnabled () { return logger.isWarnEnabled (); }
public boolean isErrorEnabled() { return logger.isErrorEnabled(); }
//---
//<<< log >>>
// (String msg)
public void trace(String msg) { logger.log(MARKER, FQCN, TRACE_INT, msg, null, null); }
public void debug(String msg) { logger.log(MARKER, FQCN, DEBUG_INT, msg, null, null); }
public void info (String msg) { logger.log(MARKER, FQCN, INFO_INT, msg, null, null); }
public void warn (String msg) { logger.log(MARKER, FQCN, WARN_INT, msg, null, null); }
public void error(String msg) { logger.log(MARKER, FQCN, ERROR_INT, msg, null, null); }
// (String msg, Throwable t)
public void trace(String msg, Throwable t) { logger.log(MARKER, FQCN, TRACE_INT, msg, null, t ); }
public void debug(String msg, Throwable t) { logger.log(MARKER, FQCN, DEBUG_INT, msg, null, t ); }
public void info (String msg, Throwable t) { logger.log(MARKER, FQCN, INFO_INT, msg, null, t ); }
public void warn (String msg, Throwable t) { logger.log(MARKER, FQCN, WARN_INT, msg, null, t ); }
public void error(String msg, Throwable t) { logger.log(MARKER, FQCN, ERROR_INT, msg, null, t ); }
// (String format, Object... arguments)
public void trace(String format, Object... arguments) { logger.log(MARKER, FQCN, TRACE_INT, format, arguments, null); }
public void debug(String format, Object... arguments) { logger.log(MARKER, FQCN, DEBUG_INT, format, arguments, null); }
public void info (String format, Object... arguments) { logger.log(MARKER, FQCN, INFO_INT, format, arguments, null); }
public void warn (String format, Object... arguments) { logger.log(MARKER, FQCN, WARN_INT, format, arguments, null); }
public void error(String format, Object... arguments) { logger.log(MARKER, FQCN, ERROR_INT, format, arguments, null); }
//---
}
DemoLogApplication.java
package com.example.demo;
public class DemoLogApplication {
private static final MyLocationAwareLogger MY_LOGGER = MyLocationAwareLogger.getLogger(DemoLogApplication.class);
public static void main(String[] args) {
MY_LOGGER.info("hello");
MY_LOGGER.info("hello {}", "xxx");
MY_LOGGER.info("exception", new Exception("test"));
MY_LOGGER.info("{} {} {} exception", 1, 2, 3, new Exception("test"));
}
}
Beispiel für die Protokollausgabe(Die korrekte "Quelle der Protokollierungsanforderung" wird ausgegeben)
[[com.example.demo.DemoLogApplication.main(DemoLogApplication.java:16)]] DemoLogApplication - hello
[[com.example.demo.DemoLogApplication.main(DemoLogApplication.java:17)]] DemoLogApplication - hello xxx
[[com.example.demo.DemoLogApplication.main(DemoLogApplication.java:18)]] DemoLogApplication - exception
java.lang.Exception: test
at com.example.demo.DemoLogApplication.main(DemoLogApplication.java:18)
[[com.example.demo.DemoLogApplication.main(DemoLogApplication.java:19)]] DemoLogApplication - 1 2 3 exception
java.lang.Exception: test
at com.example.demo.DemoLogApplication.main(DemoLogApplication.java:19)
Wenn Sie nur die SLF4J-Methode "Logger" imitieren möchten, benötigen Sie keinen eigenen Logger. Wenn Sie Ihren eigenen Logger erstellen, erstellen Sie einen aussagekräftigen Logger, z. B. das Vorbereiten einer Methode für jeden Protokollausgabezweck (Überwachungsprotokoll, Leistungsprotokoll usw.). (In diesem Artikel habe ich es aus Gründen der Klarheit als Beispiel gewagt, die Methode des "Loggers" nachzuahmen. Bitte verzeihen Sie mir)
Recommended Posts