将 JUL 桥接到 SLF4J 的常用指令添加到 pom.xml
:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
添加到logback.xml
:
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
添加到Spring bean:
<bean class="org.slf4j.bridge.SLF4JBridgeHandler" init-method="install"/>
请注意,我不包括:
<bean class="org.slf4j.bridge.SLF4JBridgeHandler"
init-method="removeHandlersForRootLogger"/>
因为remove Tomcat's/JBoss's etc logging registrations 。容器注册到 JUL 的原因之一 - 将控制台输出重定向到文件,但我不确定这是否属实。
Ceki (Log4j、SLF4J 和 Logback 的作者)doesn't recommend installing SLF4JBridgeHandler
乘以倍数。但他没有解释原因...
如果两个 webapp 注册 SLF4JBridgeHandler.install()
会发生什么同时在单个 Tomcat 中?他们冲突吗?一个人会窃取其他人的所有日志消息吗?
来自 com.sun.jersey.*
的 JAXB-RS 实现使用 JUL 日志记录,我希望重定向每个应用程序的日志语句而不是系统 catalina.log
另一个奇怪的建议是输入 jul-to-slf4j.jar
进入lib/
容器的目录,不包含在应用程序中。为什么?
主题引用:
- how do I setup slf4j to handle JUL logging in a HttpServlet?
- jul-to-slf4j for specific classes only
- How to use log4j to see into Jersey
- JUL to SLF4J Bridge
- http://hwellmann.blogspot.com/2012/11/logging-with-slf4j-and-logback-in.html
- Handler error in SLF4JBridgeHandler in tomcat logs
- http://blog.cn-consult.dk/2009/03/bridging-javautillogging-to-slf4j.html
- http://www.slf4j.org/legacy.html
- http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
- http://logback.qos.ch/manual/configuration.html#LevelChangePropagator
- http://mailman.qos.ch/pipermail/logback-user/2012-August/003385.html
- http://gordondickens.com/wordpress/2012/07/30/enterprise-spring-framework-best-practices-part-3-xml-config/
- https://github.com/gordonad/enterprise-spring-best-practices/blob/master/02-application-architecture/src/main/resources/META-INF/spring/applicationContext-bootstrap.xml
最佳答案
我想说你的答案不正确(至少是最后一部分)。
(我的回答实际上不是关于多次调用 SLF4JBridgeHandler.install()
的影响,而是涵盖了您可能想要实现的场景 - 使用 jul-to Tomcat 中的多个应用程序中的 -slf4j
。)
首先你必须熟悉Tomcat's classloaders以及如何使用它们。主要思想是每个应用程序都有自己的类加载器,因此可以包含自己的jul-to-slf4j.jar
。
下一行是 JULI 、Tomcat的日志实现。仔细看看讨论自定义 LogManager
的部分:
The key component there is a custom LogManager implementation, that is aware of different web applications running on Tomcat (and their different class loaders). It supports private per-application logging configurations.
现在我们看一下jul-to-slf4j的源码。这个简单但非常强大的类,开箱即用什么都不做。要启用桥接器,您必须将 SLF4JBridgeHandler
附加到根记录器。 Ceki 为我们提供了两种选择:
- 通过调用静态方法
org.slf4j.bridge.SLF4JBridgeHandler.install()
。 - 通过在
logging.properties
文件中指定桥句柄。
ad 1)该方法处理以下代码:
java.util.logging.LogManager.getLogManager().getLogger("").addHandler(new SLF4JBridgeHandler());
但是,嘿,我们在 Tomcat 的宇宙中,我们不想使用那个丑陋的 java.util.logging.LogManager
管理器!我们希望 Tomcat 能够提供这一增强功能。所以忘记这个方法并且不要从 Tomcat 中调用它。
广告 2) 您还记得增强版 Tomcat 的 LogManager 允许所有应用程序拥有每个应用程序的日志配置吗?还记得可以在 logging.properties
文件中启用 jul-to-slf4j
吗?
要在 Tomcat 上运行的单个应用程序范围内启用/禁用 jul-to-slf4j
桥接,您必须:
- 将
jul-to-slf4j.jar
放入/app/WEB-INF/lib
中。 - 在
/app/WEB-INF/classes
中创建logging.properties
文件,其中包含以下内容:handlers=org.slf4j.bridge.SLF4JBridgeHandler
.
我在类似的问题上苦苦挣扎了几天,这个答案涵盖了我研究的一部分。希望它可以帮助您和其他人建立由 SLF4J 负责的正确环境。
关于tomcat - 在 Java EE/Spring 容器中多次使用 jul-to-slf4j 有何影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34475776/