记录器由记录器处理两次

时间:2016-01-22 03:19:48

标签: java maven log4j slf4j

我有一个我想要登录的网络应用程序。 logging.properties文件提供了一些默认日志记录,我无法对其进行影响。它记录服务器启动,关闭等等。

这些是这类日志的例子(正常的,这里没有错):

2016/01/22 12:25:10  INFO (ApplicationContext.java:671 [ServerService Thread Pool -- 64]) - Initializing Spring root WebApplicationContext
2016/01/22 12:25:13  INFO (ConfigureListener.java:202 [ServerService Thread Pool -- 64]) - Initializing Mojarra 2.1.28-jbossorg-6  for context '/MyServices'
2016/01/22 12:25:15  INFO (DeploymentHandlerUtil.java:137 [ServerService Thread Pool -- 28]) - JBAS015859: Deployed "MyServices.war" (runtime-name : "MyServices.war")
2016/01/22 12:25:15  INFO (BootstrapListener.java:93 [Controller Boot Thread]) - JBAS015874: JBoss EAP 6.4.0.GA (AS 7.5.0.Final-redhat-21) started in 27257ms - Started 485 of 520 services (63 services are lazy, passive or on-demand)

现在我也登录了我自己的方法,使用:

指定
private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(PropertiesValues.class);
...
LOG.info("Properties loaded.");

问题是,当这些日志被点击时,会导致双重记录,例如:

2016/01/22 11:50:49  INFO (AbstractLoggingWriter.java:71 [ServerService Thread Pool -- 111]) - 2016/01/22 11:50:49  INFO (EnvironmentLoader.java:128 [ServerService Thread Pool -- 111]) - Starting Shiro environment initialization.
2016/01/22 11:50:49  INFO (AbstractLoggingWriter.java:71 [ServerService Thread Pool -- 111]) - 2016/01/22 11:50:49  INFO (EnvironmentLoader.java:141 [ServerService Thread Pool -- 111]) - Shiro environment initialized in 125 ms.
...
2016/01/22 11:51:20  INFO (AbstractLoggingWriter.java:71 [http-localhost/127.0.0.1:8443-6]) - 2016/01/22 11:51:20  INFO (PropertiesValues.java:101 [http-localhost/127.0.0.1:8443-6]) - Properties loaded.

请注意,日志正在处理两次。也就是说 - 将要打印的每一行再次通过记录器运行,从而产生两个时间戳,两个日志级别和两个源。我可以通过更改log4j.properties文件中的最后一行来解决这个问题:

log4j.rootLogger=INFO, STDOUT
log4j.additivity.rootLogger=false
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.Target=System.out
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss} %5p (%F:%L [%t]) - %m%n

仅为%m但我觉得这是一个糟糕的解决方案,导致所有内容都显示为AbstractLoggingWriter.java:71

有没有办法让我的日志显示正确的方法和行号,并且格式化我选择的方式,而不是服务器?同时,我也不想丢失服务器提供的日志记录。

我的Maven依赖项是:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.5</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

3 个答案:

答案 0 :(得分:4)

我们的应用程序遇到了同样的问题,我们通过将jboss-deployment-structure.xml中的以下内容添加到Web应用程序中的WEB-INF来修复:

<?xml version="1.0" encoding="utf-8"?>
<jboss-deployment-structure>
   <deployment>
       <!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->
       <exclude-subsystems>  
           <subsystem name="logging" />
       </exclude-subsystems>  
   </deployment>
</jboss-deployment-structure>

答案 1 :(得分:1)

很难确切地说出发生了什么,但我会试着猜测。 我看到你使用JBoss,它使用commons-logging来记录事件。您将log4j设置为输出到stdout。可能来自JBoss的Logger会抓取发送到stdout的内容并将其记录下来,这样你就会有两次装饰消息。

尝试使用JBoss中的org.jboss.logging.Logger而不是slf4j 或者作为一个肮脏的技巧,您可以尝试通过添加关闭log4j输出 log4j.appender.STDOUT.Threshold=off到log4j.properties

答案 2 :(得分:0)

我对这里发生的事情的理解如下:

有两种log4j实现交错,尽管它们并非打算进行交错。

一种方法在超类中执行修饰并在当前类中记录消息。 另一个在给定的类中执行装饰和日志记录,但仍然调用超类(由于某种原因)。

现在由于类加载的混淆,超类来自log4j的一个实现(处理装饰),还有另一个类现在再次(更新版本或旧版本)处理装饰以及消息记录。

根据我的理解,这解释了为什么装饰是重复的,但整个消息没有损坏。

尝试使用

-verbose:class
jvm选项启动jboss并将输出传递给文件。这将有助于识别正在加载类的jar。

然后你可以决定这是不是你想要的东西。

相关问题