2011-02-01 65 views
1

我正在使用Java.util.Logger記錄我的項目的各種事件。我正在使用文件處理程序來創建日誌。我發現事件寫入日誌(在磁盤中)的速度幾乎是事件發生的速度。這似乎是好的和壞的在同一時間。事件更新很快就寫好了,但我很關心IO時間。有時候需要將很多數據寫入日誌。所以在這些情況下,由於這種日誌記錄,我的程序會運行得更慢,這是不可取的。爲Java記錄器優化磁盤寫入

如果有人可以建議我在這種情況下應該做什麼,這將是非常有幫助的。我不在乎事件記錄的速度,他們只需要在執行結束時在日誌文件中。

謝謝。

+0

需要注意的是,如果你在日誌事件的記憶有任何緩衝你就有可能失去這些如果你的應用程序崩潰。通常這就是你想知道的內容。 – 2011-02-01 20:22:11

回答

0

我建議你嘗試另一種日誌解決方案,如廣泛使用的log4j(通常與commons-logging結合使用)。它提供了一種高性能的日誌記錄方法。

如果你想要更多的控制,你可以實現你自己的appender。假設你需要一個文件appender,你可以覆蓋FileAppenderappend例程。

例如,

public class BatchingFileAppender extends FileAppender { 
    private List<LoggingEvent> batch = new LinkedList<LoggingEvent>; 
    public static final int BATCH_SIZE = 10; 


    @Override 
    protected void append(LoggingEvent event) { 
     batch.add(event); 

     // you can even optionally push ever 10'th or so messages to file 
     if (batch.size() == BATCH_SIZE) { 
      appendBatch(); 
     } 
    } 

    @Override 
    protected void reset() { 
     appendBatch(); 
    } 

    @Override 
    protected void closeWriter() { 
     appendBatch(); 
    } 

    private void appendBatch() { 
     for(LoggingEvent event : batch) { 
      super.append(event); 
     } 
     batch.clear(); 
    } 

} 
+0

像這樣滾動自己的緩衝區而不是使用內建的`AsyncAppender`有什麼好處? – 2011-02-01 20:08:07

+0

通過這種方法,所有的記錄事件都可以在應用程序關閉時執行(對上面的代碼進行一些小的修改)。 – 2011-02-01 20:10:56

2

的5-10%的性能損失運行完整的調試日誌時的預期。這似乎是我們的客戶可以接受的。

如果代碼生成一些內容的註銷是昂貴的,可以考慮使用一個簡單的測試,這樣避免執行這段代碼時,調試被關閉:

if (log.isLoggable(Level.FINEST)) { 
    // code to generate the log entry 
} 

您還可以創建一個java.util.logging.MemoryHandler並定期推送到文件。

+0

感謝Jochen,MemoryHandler應該適合我的應用程序。感謝你的幫助。 – Vandana 2011-02-01 20:56:57

0

使用更現代的日誌庫,如log4jslf4j具有異步/緩衝追加程序的支持。

在log4j的,你可以使用AsyncAppender(提供緩衝設施)和電線了FileAppender它:

的AsyncAppender將收集發送給它的事件,然後將它們分發到所有的附加目的地是附在它上面。您可以將多個appender附加到AsyncAppender。

的AsyncAppender使用一個單獨的線程來服務於它的緩衝區中的事件。

通過這種方式,事件以受控方式寫入磁盤,並且執行實際工作的線程不受磁盤I/O限制。

或者作爲一個簡單的選擇,考慮,如果你真的需要有日誌的全輸出運行該程序時。通過在DEBUG級別進行日誌記錄來運行生產中的應用程序通常是矯枉過正的。

+0

謝謝馬特。太棒了。 – Vandana 2011-02-01 20:57:26

1

Jochen Bedersdorfer的回答很好,just4log是一個系統,它會自動爲你做 - 通過後期處理。因此,您不必在日誌語句周圍使用if語句來增加代碼的難度。

0

您應該檢出Logback。如果我沒有弄錯的話,和log4j一樣的作者。

基於我們以前對log4j的工作,內部的logback已經 重新編寫對某些關鍵 執行路徑快十倍左右進行。不僅logback組件速度更快,而且其內存佔用空間也更小。

1

Pexus最近發佈了一個開源的性能日誌記錄軟件包PerfLog,它還包括一個基於java.util.logging。* API的應用程序日誌記錄器。它包括使用個常用工作管理異步日誌記錄的選項是所有J2EE容器availble的(1.4+) 欲瞭解更多信息,請參閱:http://www.pexus.com/perflog