陷阱 - 建立日誌訊息的開銷

TRACEDEBUG 日誌級別可以在執行時傳達給定程式碼操作的高細節。通常建議將日誌級別設定在這些以上,但是必須注意這些語句即使在看似關閉時也不會影響效能。

考慮這個日誌語句:

// Processing a request of some kind, logging the parameters
LOG.debug("Request coming from " + myInetAddress.toString() 
          + " parameters: " + Arrays.toString(veryLongParamArray));

即使將日誌級別設定為 INFO,也會在每次執行該行時評估傳遞給 debug() 的引數。這使得它在幾個方面不必要地消耗:

  • String 連線:將建立多個 String 例項
  • InetAddress 甚至可以進行 DNS 查詢。
  • veryLongParamArray 可能會很長 - 從中​​建立一個 String 消耗記憶體,需要時間

大多數日誌記錄框架提供了使用修復字串和物件引用來建立日誌訊息僅在實際記錄訊息時才會評估日誌訊息。例:

// No toString() evaluation, no string concatenation if debug is disabled
LOG.debug("Request coming from {} parameters: {}", myInetAddress, parameters));

只要可以使用 String.valueOf(Object) 將所有引數轉換為字串,這都可以很好地工作。如果日誌訊息計算更復雜,則可以在記錄之前檢查日誌級別:

if (LOG.isDebugEnabled()) {
    // Argument expression evaluated only when DEBUG is enabled
    LOG.debug("Request coming from {}, parameters: {}", myInetAddress,
              Arrays.toString(veryLongParamArray);
}

這裡,僅當 DEBUG 實際啟用時,才會處理具有昂貴的 Arrays.toString(Obect[]) 計算的 LOG.debug()