2014-03-07 32 views
5

我有一個場景,我想通過會話Id登錄到自定義Log4j Appender。換句話說,我想爲一個包設置一個記錄器(例如com.foo.bar),然後追加自定義Appender。只有當請求帶有相同的會話ID時,我想記錄消息以寫入與會話Id匹配的Appender。當我打開日誌記錄時,我們必須動態地添加一個Appender並將其名稱設置爲會話Id。我想要做的是有一個預先配置的Appender,我從log4j.xml文件中獲取並複製它,並將名稱設置爲與會話ID相同,然後將其添加到我的新記錄器中。爲了拉從配置文件中的附加器,我發現的唯一辦法是能夠做到這一點是(在這種情況下,即support_logger)一個appender連接到一個虛擬的記錄如何最好地複製配置的Log4j Appender

<appender name="console" class="org.apache.log4j.ConsoleAppender"> 
    <param name="Target" value="System.out" /> 
    <layout class="org.apache.log4j.PatternLayout"> 
     <param name="ConversionPattern" value="%-5p: %c - %m%n" /> 
    </layout> 
</appender> 

<logger name="support_logger"> 
    <level value="debug" /> 
    <appender-ref ref="console" /> 
</logger> 

通過這樣做,然後我就可以通過編碼得到的附加器:

Appender appender = Logger.getLogger("support_logger").getAppender("console")); 

問題是我現在有是,我需要創建一個新的記錄器,基於一些包,我很感興趣,然後取appender及其所有配置,並將其添加到新記錄器,但將Appender的名稱設置爲Session Id。

Logger newLogger = Logger.getLogger("com.foo.bar"); 
appender.setName(req.getSession().getId()); 
newLogger.addAppender(appender) 

出現這種情況完全在第一時間,但如果我有相同包裝的另一個會話ID,然後在「控制檯」 appender就不再出現。當我在Appender上設置名稱時,我覆蓋了控制檯配置,因爲記錄器已經初始化,似乎無法恢復。

所以我的問題是這樣的。我正在尋找一種簡單的方法來將「控制檯」appender克隆到另一個appender,並使用會話ID設置名稱,並保留原來的「控制檯」記錄器配置,以便我可以在隨後的請求中訪問它。

我已經寫了一個Appender的克隆方法,但我不確定是否有更好的方法來處理Log4j API。

回答

0

克隆的對象或更改引用對象

是的,你沒有克隆附加器,你用下面的一行將其重命名:

appender.setName(req.getSession().getId()); 

你這樣做之前,你需要創建一個深層副本。否則,您只需將現有的appender「控制檯」重命名爲「id」。如果您需要知道如何創建深層複製,請致電here is an efficient way

創建appender的深層副本後,可以使用setName對其進行重命名並將其用作appender。

詳細信息

你要求,你的新記錄器是問題:

那我現在遇到的問題是,我需要創建一個新的記錄,

這不是真的,因爲創建新的Logger是......。你無論如何都爲每個班級或每個類別做。但通常,現有的log4j配置將根據打包程序將應用的包或名稱來決定。但是,每個會話需要一個文件,因此需要一個新的appender(它自己的名稱爲文件)。

所以你真正需要做的是這樣的(僞):

Logger newLogger = Logger.getLogger("com.foo.bar"); 
FileAppender fa = null; 
Appender appender = Logger.getLogger("support_logger").getAppender("console")); 
try { 
    fa = (FileAppender) fa; 
} catch (...) { 
    // TODO: put sth here 
} 
FileAppender sessionfileappender = AppenderUtils.deepcopy(fa); 
sessionfileappender.setName(req.getSession().getId()); 
sessionfileappender.setFile("session-" + req.getSession().getId()); 
newLogger.addAppender(sessionfileappender) 

所以其實,你需要代碼的方法FileAppender AppenderUtils.deepcopy(FileAppender fa)

創建一個新的appender容易

事實上,它可能更容易只需要創建一個new FileAppender(Layout layout, String filename),看到constructor javadoc。新的僞代碼將是這樣的:

Logger newLogger = Logger.getLogger("com.foo.bar"); 
FileAppender fa = new FileAppender(
    Logger.getLogger("support_logger").getAppender("console").getLayout(), 
    "session-" + req.getSession().getId()); 
newLogger.addAppender(fa); 

更短,是吧?請記住,如果您更改佈局(該佈局還未克隆,只是對現有佈局的新引用),則會即時更改所有佈局。所以如果你需要一個新的佈局,創建一個新的佈局。