当前位置: 首页 > 知识库问答 >
问题:

Jetty 9.1:如何用log4j/slf4j获取我的webapp日志

郁烨
2023-03-14

我有一个在Jetty 9.3.6上运行的webapp,在${jetty.base}中设置为/opt/mybase/。我的webapp使用slf4j,我使用log4j作为实际的日志框架,因此我的webapp源代码中的日志语句如下所示:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SillyClass
{
    private static final Logger log = LoggerFactory.getLogger (SillyClass.class.getName ());

    ...

    public static void foo ()
    {
        if (error ())
        {
           log.error ("ERROR");
        }
        else
        {
           log.info ("NOT an error");
        }
   }

   ...

}

在我的 gradle 构建文件中,我这样做了:

dependencies {

 ...
 compile 'org.slf4j:slf4j-api:1.7.12'
 compile 'org.slf4j:slf4j-log4j12:1.7.12'
 compile 'log4j:log4j:1.2.17'
 ...
}

此配置适用于另一个(非 Jetty,非 web 应用程序)Java 项目,该项目使用相同的日志记录框架;我可以使用 ${项目.home}/src/主/资源/log4j.属性来控制日志的输出。

无论如何,当我搬到Jetty时,我按照这里的说明进行操作;但是一旦我这样做了,我就遇到了多重绑定错误。为了纠正这一点,我删除了gradle构建文件中的slf4j引用,但这导致了错误:

java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/eclipse/jetty/webapp/WebAppClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/eclipse/jetty/start/Classpath$Loader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature

然后我删除了对slf4jlog4j的所有引用(注释掉了我在上面的build.gradle中显示的三行),但我看到的错误仍然是一样的。我做错了什么?

我的/opt/mybase/资源/log4j.properties文件:

log4j.rootLogger=TRACE, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=/opt/mybase/logs/jetty.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern= %d{dd MMM yyyy HH:mm:ss.SSS} %l %m%n

任何帮助是值得赞赏的。

共有1个答案

汝和裕
2023-03-14

好吧,这是我的一个真正令人尴尬的错误。我相信,主要问题不是log4jslf4j或码头中的配置。我认为这很好。此外,尽管有多个绑定,jetty 服务器实际上还是选择了 Jetty 日志中所示的内容:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/tmp/jetty-0.0.0.0-443-webapp.war-_webapp-any-8458003046853847474.dir/webapp/WEB-INF/lib/slf4j-log4j12- 1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/mybase/webapp/lib/logging/slf4j-log4j12-  1.6.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an  explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

此外,如果一个依赖项内置了日志记录,那么你就不走运了,这取决于维护得有多好,我认为无论如何都会发生冲突。至少,我知道在这种情况下没有办法防止这种情况。

嗯,真正的问题是webapp没有自己的log4j.properties(如果您使用的是gradle,这将在$(project Home)/src/main/Resources/log4j.properties)中。我将其添加到我的项目中,我的日志记录更有意义(即,我在/opt/mybase/logs/my-silly-webapp-log.txt中看到它应该在的位置)。

最后,我报告的崩溃与此无关(在12月29日的评论中),它与Jetty 9.3.6 bug有关,该bug尚未解决,尽管在Jetty bug db中9.3.6被称为已解决。让我失望的是,日志在我最初报告的multiple_bindings错误之后立即出现。他们似乎没有关系。当我写这篇文章时,我无法在Jetty bug DB中找到确切的bug,但我最后一次检查这个bug(大约一周前)时,问题出在Jettylog4j的时候。properties(在/opt/mybase/resources/log4j.properties中)将rootLogger设置为DEBUG。当我的rootLogger出现在Jettylog4j中时,我能够重现这个错误(尽管Jetty日志相关崩溃,但websocket应用程序本身仍能正常工作)。属性设置为DEBUG。通过移动Jetty log4j的rootLogger。属性设置为INFO或更低,我可以确认问题已经解决。我会在Jetty的bug DB中提出它。

希望这对某人有帮助。

 类似资料:
  • 我正在做一个Java/J2EE项目,其中有几个Web应用程序。我想在一些webapps中介绍log4j。所以我添加了log4j-1.2。WEB-INF\lib中的16.jar和log4j。WEB-INF\classes中的属性 结果我得到一个NoClassDefFoundError: 当我试图直接在Tomcat内部安装log4j时,我也会遇到同样的错误。(我已经在tomcat/lib等中添加了pr

  • 问题内容: 许多人不确定如何将Liquibase的日志记录修复到控制台或文件中。 是否可以将liquibase日志记录到slf4j? 问题答案: 有,但是有点模糊。使用SLF4J和Log4J引用修复的liquibase日志记录: 有 简单的方法 ,通过在依赖下降: 现在,前两个是您的日常日志记录框架(slf4j api和log4j实现)。这些是您对标准log4j依赖项的补充,因为它们所做的只是路由

  • 我将slf4j与log4j一起使用,出于某种原因,除了我在代码中编写的日志之外,所有日志都显示出来——Spring日志、Hibernate日志,您可以说日志都显示在log4j中配置的级别。财产。但是,我的日志没有显示。 Maven依赖:log4j log4j 1.2.17测试 当运行 我看到我的log4j。正在使用propertes文件 我使用以下日志代码: 我的log4j.properties档

  • 我有一个使用NetBeans 7.4开发的WebApp。我将它部署在运行Tomcat7.0.47的Linux服务器上。 我的项目使用以下JAR: SLF4J-API-1.7.6.jar logback-classic-1.1.1.jar logback-core-1.1.1.jar 我的应用程序是一个SOAP服务器。在服务类的首位,我把: 私有静态最终记录器soapLogger=LoggerFac

  • 本文向大家介绍Java如何获取Log4j,包括了Java如何获取Log4j的使用技巧和注意事项,需要的朋友参考一下 示例 当前版本(log4j2) 使用Maven: 将以下依赖项添加到POM.xml文件中: 使用常春藤: 使用Gradle: 获取log4j 1.x 注意: Log4j 1.x已达到寿命终止(EOL)(请参阅备注)。 使用Maven: 在POM.xml文件中声明此依赖项: 使用常春藤

  • 我在maven项目中使用了SLF4J和log4j。当我在eclipse中用tomcat运行项目时,一切都正常,在maven中使用tomcat maven插件运行项目时。 但是当我把战争穿上我的tomcat正式服时,项目没有开始,给了我这个错误。 JAVAlang.IllegalStateException:检测到log4j-over-slf4j。jar和绑定slf4j-log4j12。类路径上的j