jul-to-slf4j
est pratique qui transfère le traitement à slf4j
même si vous vous connectez via l'API jul
.jul
est le package java.util.logging
, qui est l'API de journalisation par défaut en Java.slf4j
est une bibliothèque de façades en rondins.slf4j
, les multiples systèmes de traitement mentionnés ci-dessus se réfèrent à chaque bibliothèque de journalisation telle que logback
etlog4j (2)
, et servent d'interface pour ces traitements.logback
et log4j2
ces jours-ci. Les paramètres de chaque bibliothèque de journalisation qui fonctionne réellement ne peuvent pas être supprimés.
À part *, beaucoup de choses dépendent de ce type.jul
, mais même dans ce cas, c'est celle qui permet au traitement d'être transféré de manière transparente vers slf4j
. C'est jul-to-slf4j
.jul-to-slf4j
.SLF4JBridgeHandler.install();
Juste frappe le.
Spring Boot
[URL de référence](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/Slf4JLoggingSystem .Java)
Slf4jLoggingSystem.java
...
private void configureJdkLoggingBridgeHandler() {
try {
if (isBridgeHandlerAvailable()) {
removeJdkLoggingBridgeHandler();
SLF4JBridgeHandler.install();
}
}
catch (Throwable ex) {
// Ignore. No java.util.logging bridge is installed.
}
}
...
Play framework
LogbackLoggerConfigurator.scala
...
def configure(properties: Map[String, String], config: Option[URL]): Unit = {
// Touching LoggerContext is not thread-safe, and so if you run several
// application tests at the same time (spec2 / scalatest with "new WithApplication()")
// then you will see NullPointerException as the array list loggerContextListenerList
// is accessed concurrently from several different threads.
//
// The workaround is to use a synchronized block around a singleton
// instance -- in this case, we use the StaticLoggerBinder's loggerFactory.
loggerFactory.synchronized {
// Redirect JUL -> SL4FJ
// Remove existing handlers from JUL
SLF4JBridgeHandler.removeHandlersForRootLogger()
// Configure logback
val ctx = loggerFactory.asInstanceOf[LoggerContext]
// Set a level change propagator to minimize the overhead of JUL
//
// Please note that translating a java.util.logging event into SLF4J incurs the
// cost of constructing LogRecord instance regardless of whether the SLF4J logger
// is disabled for the given level. Consequently, j.u.l. to SLF4J translation can
// seriously increase the cost of disabled logging statements (60 fold or 6000%
// increase) and measurably impact the performance of enabled log statements
// (20% overall increase). Please note that as of logback-version 0.9.25,
// it is possible to completely eliminate the 60 fold translation overhead for
// disabled log statements with the help of LevelChangePropagator.
//
// https://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
// https://logback.qos.ch/manual/configuration.html#LevelChangePropagator
val levelChangePropagator = new LevelChangePropagator()
levelChangePropagator.setContext(ctx)
levelChangePropagator.setResetJUL(true)
ctx.addListener(levelChangePropagator)
SLF4JBridgeHandler.install()
ctx.reset()
// Ensure that play.Logger and play.api.Logger are ignored when detecting file name and line number for
// logging
val frameworkPackages = ctx.getFrameworkPackages
frameworkPackages.add(classOf[play.Logger].getName)
frameworkPackages.add(classOf[play.api.Logger].getName)
properties.foreach { case (k, v) => ctx.putProperty(k, v) }
config match {
case Some(url) =>
val initializer = new ContextInitializer(ctx)
initializer.configureByResource(url)
case None =>
System.err.println("Could not detect a logback configuration file, not configuring logback")
}
StatusPrinter.printIfErrorsOccured(ctx)
}
}
...
Ugh, scala
...
Ça ressemble à ça.
SLF4JBridgeHandler.java
public static void install() {
LogManager.getLogManager().getLogger("").addHandler(new SLF4JBridgeHandler());
}
...
public void publish(LogRecord record) {
// Silently ignore null records.
if (record == null) {
return;
}
Logger slf4jLogger = getSLF4JLogger(record);
// this is a check to avoid calling the underlying logging system
// with a null message. While it is legitimate to invoke j.u.l. with
// a null message, other logging frameworks do not support this.
// see also http://jira.qos.ch/browse/SLF4J-99
if (record.getMessage() == null) {
record.setMessage("");
}
if (slf4jLogger instanceof LocationAwareLogger) {
callLocationAwareLogger((LocationAwareLogger) slf4jLogger, record);
} else {
callPlainSLF4JLogger(slf4jLogger, record);
}
}
Dès la conclusion, si vous suivez les étapes de ce qui se fait
SLF4JBridgeHandler
qui hérite de java.util.logging.Handler
au journal racine sur jul
avecSLF4JBridgeHandler # install ()
java.util.logging.logger # info ()
etc., [en quelque sorte](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6- b14 / java / util / logging / Logger.java # Logger.log% 28java.util.logging.LogRecord% 29) Un processus est transféré vers java.util.logging.Handler # publish ()
SLF4JBridgeHandler # publish ()
transfère en outre le traitement de l'enregistreur de Slf4j
, la journalisation via jul
se fait en exécutant SLF4JBridgeHandler # install ()
. Le traitement est transféré vers.Qui est java.util.logging.Handler
par JavaDoc Quand,
L'objet Handler reçoit les messages du journal de Logger et les exporte. Par exemple, cet objet écrit dans la console ou le fichier, l'envoie au service de journalisation du réseau, effectue des transferts vers le journal du système d'exploitation, etc.
Il y a.
En d'autres termes, «Logger» est une interface vue depuis l'application, et est-ce comme ce «Handler» qui produit réellement des journaux physiques?
J'ai en quelque sorte compris que c'était comme un appender dans logback
.
Et qu'est-ce que LogManager
? Pour autant que je lis l'instruction ʻimport`, c'est une classe de jul.
SLF4JBridgeHandler.java
import java.util.logging.LogManager;
De plus, vous pouvez voir que le nom de l'enregistreur est spécifié comme un caractère vide, tel que getLogger (" ")
. Qu'est-ce que c'est?
Ce n'est pas que je ne peux pas l'imaginer car il n'a pas de nom, mais il semble que vous puissiez obtenir un enregistreur racine en spécifiant un nom d'enregistreur vide.
SLF4JBridgeHandler.java
private static java.util.logging.Logger getRootLogger() {
return LogManager.getLogManager().getLogger("");
}
Comme prémisse ici, tous les loggers ont une relation descendante avec jul
ainsi qu'avec d'autres exemples d'API de journalisation, et héritent toujours de la route.
Cela signifie que l'ajout d'un SLF4JBridgeHandler
à l'enregistreur racine sur jul
signifie que toute journalisation via jul
sera déléguée à slf4j
.
GC: Logger - java.util.logging.Logger (.java) - GrepCode Class Source
Finalement trouvé, java.util.logging - WebLog d'Akira Koyasu
Recommended Posts