首页 文章

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

提问于
浏览
2

通常将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/ 目录中,不包括应用程序 . 为什么?

REFERENCE ON THE TOPIC

2 回答

  • 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 附加到根 Logger . Ceki为我们提供了两种选择:

    • 通过调用静态方法 org.slf4j.bridge.SLF4JBridgeHandler.install() .

    • 通过在 logging.properties 文件中指定桥接句柄 .

    ad 1) 以下代码的方法流程:

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

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

    ad 2) 你还记得,启用Tomcat的LogManager允许所有应用程序拥有 per-application logging configurations 对吗?请记住 jul-to-slf4j 可以在 logging.properties 文件中启用吗?


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

    • jul-to-slf4j.jar 放入 /app/WEB-INF/lib .

    • /app/WEB-INF/classes 内创建 logging.properties 文件,内容如下: handlers=org.slf4j.bridge.SLF4JBridgeHandler .


    我在几天内遇到了类似的问题,这个答案涵盖了我研究的一部分 . 希望它可以帮助您和其他人在SLF4J负责的情况下 Build 正确的环境 .

  • 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的单个实例,并从系统类加载,否则您很难解释问题 .

相关问题