【问题标题】:log from static method using Log4j2使用 Log4j2 从静态方法记录日志
【发布时间】:2016-09-15 11:51:35
【问题描述】:

我正在尝试在 OSGi 环境中使用 Log4j2。到目前为止,我已经让它工作了,但是在从控制台和文件中检查日志时,我注意到其中一些丢失了,特别是从静态方法调用的日志。 下面示例中的Log 类只是一个方便类,它可以让我的同事通过create 方法更轻松地调用日志记录功能(在示例中只是String,当然这似乎有点矫枉过正)。它只不过是创建了一个 Log 类的实例,该实例在内部有一个 Logger,它从 Log4j2 记录器中调用相应的方法。

我的问题是:我的项目中是否只有一个简单的错误,或者 Log4j2 不能能够从静态方法记录到文件?

下面是一个代码示例,使其更加清晰:

Log log = Log.testLog();
    log.info("non static log" );

这是我从非静态方法调用的代码。 这是testLog()-方法:

public static Log testLog() {
    Log.create( Log.class ).info( "static log" );
    return Log.create( Log.class );
}

结果: 两个 #info() 调用都写入控制台 Appender,但将“非静态日志”消息写入文件。

这是我的log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>


<Appenders>
    <Console name="Console">
        <PatternLayout pattern="!ENTRY %logger{1.} %level %d{DEFAULT} [%t]%n!MESSAGE %msg%n%n"/>
    </Console>

    <RollingFile name="RollingFile" fileName="${sys:osgi.logfile}.log4j.log"
            filePattern="${sys:osgi.logfile}.log4j_bak_%i.log">
        <PatternLayout>
            <pattern>!ENTRY %logger{1.} %level %d{DEFAULT} [%t]\n!MESSAGE %msg%n%n</pattern>
        </PatternLayout>
        <Policies>
            <SizeBasedTriggeringPolicy size="1 MB"/>
        </Policies>
        <DefaultRolloverStrategy max="10"
            fileIndex="min"/>
    </RollingFile>
  </Appenders>

  <Loggers>
    <Root level="TRACE" additivity="false">
        <AppenderRef ref="RollingFile"/>
        <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

【问题讨论】:

  • 你为什么不给Log.create( Log.class )打一次电话?
  • 这会改变什么吗?这背后真的没有任何原因,我只是为了测试目的而快速地将方法拍打在一起。
  • 我不确定,但我可以想象重新创建 Log 实例可能会清除缓冲区。除此之外,我们通常使用 log4j 的包装器,例如 slf4j 或 commons logging,因此使用工厂来创建记录器,但 AFAIK log4j 提供了类似的东西,可能出于完全相同的原因,即您应该只创建某个记录器一次然后重用那个实例。
  • 该工厂(或来自 log4j2 的类似构造)可以是 LogManager 吗?如果是这样,这就是我的 Log 类在其核心使用的构造。
  • 正如我所说,我不是 log4j 专家,但听起来就是这样。在这种情况下,您可能应该发布Log.create() 的相关部分。

标签: java osgi log4j2


【解决方案1】:

终于找到了我的特殊问题的根源,即 OSGi(在本例中是 Equinox 框架)。我的应用程序使用osgi.logfile 系统属性指向应保存日志的位置。

不幸的是,Equinox 不仅会创建该属性,还会在启动时将其更改为不同的位置。对于 Log4j2,我使用 ${sys:osgi.logfile} 来获取此系统属性,但由于一些特定的插件启动得太早,Log4j2 仍然为这些插件配置了错误的(又名旧的)位置(更具体地说:它们的 LoggerContext)。

在这种情况下帮助我的是LoggerContext 上的一个简单的LoggerContext.reconfigure(),它仍然具有旧位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 2016-01-26
    • 1970-01-01
    • 2017-12-20
    • 2014-10-30
    • 2021-08-28
    • 2017-05-18
    相关资源
    最近更新 更多