在Java EE / Spring容器中多次使用jul-to-slf4j有什么影响?

时间:2015-12-26 22:19:23

标签: tomcat jaxb slf4j logback java.util.logging

将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在单个Tomcat中同时注册SLF4JBridgeHandler.install(),会发生什么?他们有冲突吗?是否有人从其他人那里窃取所有日志消息?

来自com.sun.jersey.*的JAXB-RS实现使用JUL日志记录,我希望每个应用程序而不是系统catalina.log重定向日志语句

另一个奇怪的建议是将jul-to-slf4j.jar放入容器的lib/目录中,不包括应用程序。为什么呢?

参考主题

2 个答案:

答案 0 :(得分:2)

我会说你的答案不正确(至少在答案的最后部分)。

(我的答案实际上不是关于多次调用SLF4JBridgeHandler.install()的影响,而是涵盖了您可能想要实现的场景 - 在Tomcat中的多个应用程序中使用jul-to-slf4j。)

首先,您必须熟悉Tomcat's classloaders以及如何使用它们。主要思想是每个应用程序都有自己的类加载器,因此可以包含它自己的jul-to-slf4j.jar

下一行是JULI,Tomcat的日志记录实现。仔细查看有关自定义LogManager的部分:

  

关键组件有一个自定义LogManager实现,即   了解在Tomcat上运行的不同Web应用程序(以及它们的   不同的班级装载机)。它支持私有的每应用程序日志记录   配置。

现在让我们来看看jul-to-slf4j的源代码。这个简单而又非常强大的课程开箱即用 nothing 。要启用网桥,您必须将SLF4JBridgeHandler附加到根记录器。 Ceki为我们提供了两种选择:

  1. 通过调用静态方法org.slf4j.bridge.SLF4JBridgeHandler.install()
  2. 通过在logging.properties文件中指定桥接句柄。
  3. ad 1)以下代码的方法流程:

    java.util.logging.LogManager.getLogManager().getLogger("").addHandler(new SLF4JBridgeHandler());
    

    但是,嘿,我们在Tomcat的宇宙中,我们不想使用那个丑陋的java.util.logging.LogManager经理!我们希望增强的一个与Tomcat一起使用。所以忘记这个方法,不要在Tomcat中调用它。

    ad 2)您还记得,Tomcat的LogManager允许所有应用程序拥有每个应用程序的日志记录配置吗?请记住,jul-to-slf4j文件可以在logging.properties文件中启用吗?

    要在Tomcat上运行的单个应用程序范围内启用/禁用jul-to-slf4j网桥,您必须:

    1. jul-to-slf4j.jar放入/app/WEB-INF/lib
    2. logging.properties中创建/app/WEB-INF/classes个文件,其中包含以下内容:handlers=org.slf4j.bridge.SLF4JBridgeHandler
    3. 我在几天内遇到了类似的问题,这个答案涵盖了我研究的一部分。希望它可以帮助您和其他人在SLF4J负责的情况下建立正确的环境。

答案 1 :(得分:0)

我打开了改进文档的请求: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.

因此,在多应用程序容器环境中,jul-to-slf4j应该是每个JVM的单个实例,并从系统类加载,否则很难解释问题。