繁体   English   中英

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

[英]Jetty 9.1+: how to get my webapp logs with log4j/slf4j

我有一个在${jetty.base} Jetty 9.3.6上运行的webapp,它设置为/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'
 ...
}

此配置对于另一个使用相同日志记录框架的Java项目(非Jetty,非Webapp)非常有效。 我可以使用${project.home}/src/main/resources/log4j.properties来控制日志的输出。

无论如何,当我搬到码头时,我按照此处的指示进行操作。 但是,一旦这样做,我就遇到了多重绑定错误 为了更正此问题,我在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显示的build.gradle ),但是看到的错误仍然相同。 我究竟做错了什么?

我的/opt/mybase/resources/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

任何帮助表示赞赏。

好吧,这对我来说确实是一个令人尴尬的错误。 我认为,主要问题不是log4jslf4j或码头配置。 我认为效果很好。 此外,尽管多个绑定,码头服务器实际上选择在码头日志这里显示的内容

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,它将在$(projectHome)/src/main/resources/log4j.properties) 我将其添加到项目中,并且日志记录变得更加有意义(即,我在/opt/mybase/logs/my-silly-webapp-log.txt可以看到它的位置)。

最后,我报告的崩溃与无关(在12月29日的评论中),与Jetty 9.3.6错误有关,尽管尚未在9.36的Jetty错误数据库中解决,但它尚未解决。 让我失望的是,这些日志在我最初报告的multiple_bindings错误之后立即出现。 它们不相关,看起来。 在撰写本文时,我无法在Jetty错误数据库中找到确切的错误,但是最后一次检查该错误(大约一周前)时,问题出在Jetty log4j.properties (在/opt/mybase/resources/log4j.properties )已将rootLogger设置为DEBUG (从对该错误的评论中了解了这一点)。 当我rootLogger Jetty log4j.properties rootLogger设置为DEBUG时,我能够重现该错误(尽管与Jetty日志相关的崩溃,websocket应用程序本身也能正常工作)。 通过将Jetty log4j.propertiesrootLogger移至INFO或更低的级别,我可以确认问题已经消除。 我将在Jetty的bug数据库中提出它。

希望这对某人有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM