【问题标题】:How to separately logging JBoss server specific logs with JBoss Logging and application specific logs with log4j?如何使用 JBoss Logging 分别记录 JBoss 服务器特定的日志和使用 log4j 的应用程序特定的日志?
【发布时间】:2018-01-12 15:46:47
【问题描述】:

我们正在将我们的应用程序从 WebSphere 迁移到 JBoss EAP 6.4。我在网上看到,从 JBoss EAP 6.x 开始,JBoss 使用自己的日志框架,称为 JBoss Logging,而不是之前的 log4j。

我们已经有一个用于应用程序特定日志的 log4j.properties 文件,它根据日志级别(log-error.log、log-info.log、...)将日志存储在单独的文件中,但实际上它们也是登录控制台和 server.log 文件。

一方面,我们希望仅使用我们现有的 log4j.properties 配置文件记录应用程序日志,但也阻止它们在 server.log 和控制台中登录。 p>

另一方面,我们希望使用 JBoss Logging 框架记录服务器特定的日志,因此在 server.log 和控制台中。

总结一下,我们想从:

application logs + server logs => server.log/console + separate file logs

到这里:

application logs => seperate file logs
server logs => server.log/console

有人知道如何做到这一点吗? 有没有人已经以类似的方式配置了 JBoss 服务器?

谢谢你,

问候。

【问题讨论】:

    标签: java jboss slf4j jboss-eap-6 jboss-logging


    【解决方案1】:

    我花了几天的时间来解决这个问题,我认为我有一些可行的方法。我正在使用 EAP 6.4。

    首先,上面提到的关于将代码添加到 standalone.xml 的解决方案使下面描述的解决方案的输出在控制台中更易于阅读。如果您不执行该步骤,您会在控制台中获得一些额外的换行符。

    我所做的是创建一个log4j.xml 文件,但我确实将其称为log4j.xml。对于我的 2 个应用程序,我将其命名为 servicelog4j.xml。这意味着 JBoss 不会找到它。

    然后,当我创建 log4j 记录器时,我执行以下操作(这是在我的类名为 Log4jLogger 的静态方法中):

    public static Logger getLogger(Class aClass) {
        ClassLoader classLoader = Log4jLogger.class.getClassLoader();
        InputStream log4JStream = classLoader.getResourceAsStream("servicelog4j.xml");
        if (log4JStream != null) {
            new DOMConfigurator().doConfigure(log4JStream, LogManager.getLoggerRepository());
        }
    
        Logger log = Logger.getLogger(aClass);
        return log;
    }
    

    现在,servicelog4j.xml 文件位于我的 Eclipse 项目的资源文件夹中,因此在部署应用程序时,它将被复制到 WEB-INF/classes/servicelog4j.xml

    该文件的内容是标准的 log4j 文件。我有一个标准文件附加程序和一个控制台附加程序。每个应用程序的文件附加程序指向不同的文件。

    要让我的类的调试代码出现在控制台(和文件中),我将以下内容放在servicelog4j.xml 中(因为我的所有代码都在包com.mycompany.mypackage 中):

      <logger name="com.mycompany.mypackage">
          <level value="debug" />
          <appender-ref ref="CONSOLE" />
      </logger>
      <root>
          <priority value ="info" />
          <appender-ref ref="FILE" />
      </root>
    

    通过上述配置,我可以在 Eclipse 控制台以及文件中获得所有消息。如果我只是删除 &lt;logger&gt; 部分,那么调试消息将无处可去,这正是我在生产中想要的。

    【讨论】:

      【解决方案2】:

      不明白为什么,但 log4j 也会登录 stdout,因此 JBoss Logging 会捕获这些日志并将它们再次附加到 JBoss 控制台和 server.log,如下所示:

      2017-08-08 15:14:20,304 INFO [stdout] &lt;&lt;My log4j log message&gt;&gt;

      我暂时成功地通过将该代码添加到 standalone.xml 文件来防止这种情况发生:

      <logger category="stdout" use-parent-handlers="false">
          <level name="OFF"/>
      </logger>
      

      这不是一个坏习惯吗?

      谢谢,

      【讨论】:

      • 如果有任何内容写入System.out,则不会被记录。那将是唯一的问题。
      • 不要认为这会是一个问题,在我们的应用程序中使用 System.out 是非常不鼓励的,但在这种情况下,你认为我可以在我的 log4j.properties 文件中声明一个标准输出记录器吗? log4j.logger.stdout = INFO, outAppender 之类的东西?只是为了确保我们不会丢失日志并找到 System.out 调用以删除它们。
      • 可能不会。 JBoss EAP 将System.setOut()System.setErr() 替换为由记录器支持的流。这是为了防止有人写入其中一个流并且控制台流被丢弃。
      【解决方案3】:

      如果您在WAR/WEB-INF/classesEAR/META-INF 中包含log4j.proeprties 文件,它应该可以正常工作。如果您在所有地方都看到特定于应用程序的日志记录,那么我的猜测是您在 log4j.properties 文件中配置了一个控制台附加程序。

      【讨论】:

      • 在我的 log4j 属性文件中删除控制台附加程序后,它仍然无法正常工作。有什么想法吗?
      • 是 WAR 还是 EAR 部署?你使用 log4j 作为你的日志框架吗?
      • 这是一个 EAR 部署。是的,我们是的。我们将 log4j 与自制的日志记录层一起使用,它调用 log4j 日志记录方法以及额外的日志信息聚合。
      • 不明白为什么,但是 log4j 也会登录 stdout,所以 JBoss Logging 捕获这些日志并通过将它们附加到 JBoss 控制台和 server.log 中再次处理它们,如下所示:INFO [stdout] &lt;&lt;My log4j log message&gt;&gt;
      • 因此,如果您看到 [stdout] 日志并且正在使用 ConsoleApppender,那么看起来 JBoss EAP 正在查看您的日志配置。 JBoss EAP 确实将 stdoutstderr 包装在记录器中。
      猜你喜欢
      • 2011-06-24
      • 2014-12-25
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 2017-06-04
      • 1970-01-01
      相关资源
      最近更新 更多