2016-09-15 679 views
2

我想在OSGi环境中使用Log4j2。到目前为止,我已经掌握了它的工作原理,但在检查控制台和文件中的日志时,我注意到其中一些文件丢失了,特别是从静态方法中调用的日志。 下面例子中的Log类只是一个便利的类,让我的同事通过创建方法更容易地调用日志记录功能(在本例中只是String,看起来像是过度杀毒)。它只不过是创建一个内部有Logger的Log类的实例,它调用Log4j2记录器中的相应方法。从静态方法使用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()调用写入控制台追加程序,但只“非静态日志”消息被写入文件。

这里是我的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> 
+0

为什么不直接调用'Log.create(Log.class)'? – Thomas

+0

这会改变什么吗?这背后确实没有什么理由,我只是很快将这种方法一起用于测试目的。 –

+0

我不确定,但我可以想象,重新创建'Log'实例可能会清除缓冲区。除此之外,我们通常使用log4j的包装器,例如slf4j或commons logging,因此使用工厂来创建记录器,但AFAIK log4j提供了类似的东西,可能出于完全相同的原因,也就是说,您应该只创建一次某个记录器,然后重新使用那个例子。 – Thomas

回答

1

终于找到了我特别的问题,这是OSGi的(在这种情况下,春分框架)的来源。我的应用程序使用osgi.logfile系统属性来指向日志应该保存在的位置。

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

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