2011-06-12 49 views
3

我在寫一個log4j appender,它通過http發送日誌到服務器。我想從apache-commons中使用HttpClient讓我的代碼更加簡單。在log4j Appender中記錄時的循環依賴

現在的問題是,HttpClient和Co.使用log4j本身。通常是件好事,但在log4j appender實現中調用它們時,會引入循環引用或無限循環,最終導致OutOfMemoryException。

當然,我可以在沒有任何第三方庫的情況下編寫我想要的東西,但我只是想知道這種問題是否已知解決方案?

回答

3

這是一個很好的問題!很遺憾,log4j不會在這裏幫助你。但是我們可能會迂迴,並使用log4j來修復log4j!最重要的概念是一個Diagnostic Context

private static final String IN_APPEND_KEY = MyAppender.class.getName() + ".inAppend"; 
public void append(LoggingEvent e) { 
    if (e.getMDC(IN_APPEND_KEY) != null) return; 
    MDC.put(IN_APPEND_KEY, this); 
    try { 
     <your code here> 
    } finally { 
     MDC.remove(IN_APPEND_KEY); 
    } 
} 

你基本上要設置一個標誌,將「旅遊」與您的appender的執行流程。至少在理論上,這正是一種診斷情境。它是線程本地的並跨線程繼承。仔細編寫的代碼甚至可以保留跨越其他邊界的上下文,如消息隊列。這會有多酷:你的appender將日誌消息放在HTTP請求隊列中,隊列保存診斷上下文並在請求運行時將其恢復,HTTP庫記錄錯誤,並且你的appender仍然檢測到循環!這幾乎是你可以要求的最好的事情。

0

爲什麼Apache HttpClient的記錄器使用你的Appender?給它另一個Appender,控制檯或其他東西。

+0

好點。但是如果稍後有人重新配置它,問題仍然會發生。我想使它成爲「可釋放的」...... – raoulsson 2011-06-12 11:49:18

+0

檢查它是否會給出循環行爲並拋出異常來解釋原因。 – 2011-06-12 11:52:48