2016-09-15 682 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(),它仍然有舊的位置。