在 Java EE / Spring 容器中多次使用 jul-to-slf4j 有什么影响?
What is impact of using jul-to-slf4j several times in Java EE / Spring container?
将 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 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 (author of Log4j, SLF4J and Logback) doesn't recommend installing SLF4JBridgeHandler
相乘。但是他没有解释为什么...
如果两个 webapp 在一个 Tomcat 中同时注册 SLF4JBridgeHandler.install()
会发生什么?他们有冲突吗?一个人是否窃取了另一个人的所有日志消息?
来自 com.sun.jersey.*
的 JAXB-RS 实现使用 JUL 日志记录,我希望每个应用程序而不是系统重定向日志语句 catalina.log
另一个奇怪的建议是将 jul-to-slf4j.jar
放入容器的 lib/
目录中,不要包含在应用程序中。为什么?
主题参考:
- 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
我提出改进文档的请求:http://jira.qos.ch/browse/SLF4J-351
响应是:
There is one j.u.l.LogManager instance per JVM.
Thus, any manipulation of it impacts the whole JVM.
所以在 multi-application 容器环境中 jul-to-slf4j 应该是每个 JVM 的单个实例并从系统加载 类 否则你很难解释问题。
我会说你的回答不正确(至少最后一部分)。
(我的回答实际上不是关于多次调用 SLF4JBridgeHandler.install()
的影响,而是涵盖您可能想要实现的场景 - 在多个应用程序中使用 jul-to-slf4j
在 Tomcat.)
首先,您必须熟悉 Tomcat's classloaders 及其使用方法。主要思想是每个应用程序都有自己的 classloader 因此可以包含它自己的 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的源代码。这个简单但非常强大的class,开箱即用没有。要启用桥接,您必须将 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.
中调用它
ad 2) 你记得 enahnced Tomcat 的 LogManager 允许所有应用程序具有 per-application 日志记录配置正确的?还记得 jul-to-slf4j
可以在 logging.properties
文件中启用吗?
要在enable/disablejul-to-slf4j
桥接运行范围内对Tomcat单人申请你必须:
- 将
jul-to-slf4j.jar
放入/app/WEB-INF/lib
。
- 在
/app/WEB-INF/classes
内创建 logging.properties
文件,内容如下:handlers=org.slf4j.bridge.SLF4JBridgeHandler
.
几天来我一直在为类似的问题而苦苦挣扎,这个答案涵盖了我研究的一部分。希望它可以帮助您和其他人设置正确的 SLF4J 环境。
将 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 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 (author of Log4j, SLF4J and Logback) doesn't recommend installing SLF4JBridgeHandler
相乘。但是他没有解释为什么...
如果两个 webapp 在一个 Tomcat 中同时注册 SLF4JBridgeHandler.install()
会发生什么?他们有冲突吗?一个人是否窃取了另一个人的所有日志消息?
来自 com.sun.jersey.*
的 JAXB-RS 实现使用 JUL 日志记录,我希望每个应用程序而不是系统重定向日志语句 catalina.log
另一个奇怪的建议是将 jul-to-slf4j.jar
放入容器的 lib/
目录中,不要包含在应用程序中。为什么?
主题参考:
- 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
我提出改进文档的请求:http://jira.qos.ch/browse/SLF4J-351
响应是:
There is one j.u.l.LogManager instance per JVM.
Thus, any manipulation of it impacts the whole JVM.
所以在 multi-application 容器环境中 jul-to-slf4j 应该是每个 JVM 的单个实例并从系统加载 类 否则你很难解释问题。
我会说你的回答不正确(至少最后一部分)。
(我的回答实际上不是关于多次调用 SLF4JBridgeHandler.install()
的影响,而是涵盖您可能想要实现的场景 - 在多个应用程序中使用 jul-to-slf4j
在 Tomcat.)
首先,您必须熟悉 Tomcat's classloaders 及其使用方法。主要思想是每个应用程序都有自己的 classloader 因此可以包含它自己的 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的源代码。这个简单但非常强大的class,开箱即用没有。要启用桥接,您必须将 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.
ad 2) 你记得 enahnced Tomcat 的 LogManager 允许所有应用程序具有 per-application 日志记录配置正确的?还记得 jul-to-slf4j
可以在 logging.properties
文件中启用吗?
要在enable/disablejul-to-slf4j
桥接运行范围内对Tomcat单人申请你必须:
- 将
jul-to-slf4j.jar
放入/app/WEB-INF/lib
。 - 在
/app/WEB-INF/classes
内创建logging.properties
文件,内容如下:handlers=org.slf4j.bridge.SLF4JBridgeHandler
.
几天来我一直在为类似的问题而苦苦挣扎,这个答案涵盖了我研究的一部分。希望它可以帮助您和其他人设置正确的 SLF4J 环境。