在Log4j2中更好地执行非日志记录器调用
使用Log4j 1.x并希望避免在某些情況下可能會造成額外的性能影響(即使實際上未記錄該消息)時,通常使用日志記錄防護 。 Java的簡單日志記錄外觀 ( SLF4J )帶給Java日志記錄的最吸引人的功能之一是能夠減少需要進行這些日志級別檢查的情況的數量 。 在本文中,我將探討如何使用Log4j 2.x的日志記錄API更改來實現類似的好處。
下一個代碼清單演示了記錄長時間運行的操作。 第一個示例在名稱為“ slow”的實例上隱式調用toString()方法。 第二個日志記錄示例調用了一個長時間運行的方法。
傳統,無人值守的日志記錄
// Will implicitly invoke slow's toString() method logger.debug("NORMAL: " + slow); // Will explicitly invoke the long-running method expensiveOperation() logger.debug(expensiveOperation());在前面的示例中,即使實際上未執行任何日志記錄,這兩個日志記錄操作也將花費很長時間。 先前代碼清單中的日志記錄語句僅在日志記錄級別為DEBUG或不太明確的日志級別(例如TRACE)時才實際記錄,但是即使不進行任何記錄,它們的昂貴操作也將運行。
在Log4j 1.x中,有兩種方法可以解決此問題。 一種方法(通常是最好的方法)是嘗試重新編寫log語句,以便不涉及長時間運行的操作 。 如果這不切實際(例如,當需要與長時間運行的操作相關聯的上下文以使日志消息有用時),則可以使用日志保護。 接下來演示在Log4j 1.x中有效的方法。
傳統的,受保護的日志記錄
if (logger.isDebugEnabled()) {logger.debug("GUARDED: " + slow);logger.debug(expensiveOperation()); }如前面的代碼清單所示,日志防護措施可以有效地防止調用長時間運行的操作,即使無論如何也不會記錄任何消息。 但是,使用日志保護確實會帶來一些缺點。 也許最主要的缺點是引入了額外的(有些人會說是)腫的)代碼。 另一個潛在的缺點很少見,但更為嚴重:由于條件塊和關聯塊引入了額外的作用域,因此它更容易在條件塊中引入錯誤代碼,甚至有可能在依賴于日志記錄級別的情況下帶來副作用代碼塊。
最常見的情況之一是,日志調用實際上不會記錄任何內容,但會顯著影響性能,這是當將對象傳遞給logger調用或與傳遞給該字符串的字符串連接時,顯式或隱式調用對象的toString()方法。記錄器調用。 在上面的兩個代碼清單中,通過將字符串文字“ GUARDED:”與名為“ slow”的變量的隱式調用toString()方法進行連接,將該字符串傳遞給logger調用,從而證明了這種情況。
SLF4J 普及了參數化日志記錄調用的概念,Log4j 2在其日志記錄API中提供了類似的支持 。 下面的代碼演示了如何使用它。
參數化記錄
logger.debug("PARAMETERIZED: {}", slow); logger.debug("{}", expensiveOperation());當使用比DEBUG更特定的日志級別執行上述參數化日志記錄示例時,由于進行了參數化日志記錄,因此將不會嘗試在“ slow”變量上使用隱式toString() 。 但是,參數化日志記錄無法幫助其他日志記錄情況,因為盡管進行了參數化日志記錄,但仍將調用方法expensiveOperation() 。 還要注意,雖然參數化日志記錄在隱式toString()調用的情況下有所幫助 ,但在顯式toString()調用中卻無濟于事 。 即使日志記錄級別比DEBUG更具體,在logger語句中對slow.toString()的調用仍會導致性能slow.toString() 。
Log4j 2.4引入了一種基于Lambda的機制 ,該機制可用于延遲對傳遞給logger調用的方法的調用,這樣,如果該語句的記錄級別低于當前日志級別,則根本不需要執行它們。 。 這表現在下一代碼列表,其中toString()方法被明確地通過λ表達式稱為“慢”變量的對象上,并且expensiveOperation方法是通過調用方法的參考 。
Lambda表達式記錄
logger.debug("LAMBDA: ", () -> slow.toString()); logger.debug("{}", this::expensiveOperation);當上述代碼的日志級別設置為比DEBUG更特定的級別時,由于基于lambda表達式的延遲加載,因此不會調用“慢”對象的toString()方法和expensiveOperation方法。 換句話說,類似于該示例與警衛一起使用的方式,使用lambda表達式可以防止不必要地執行可能長時間運行的方法,除非要真正記錄它們的結果。 此lambda表達式支持已在2.4版中添加到Log4j,并且當然需要Java 8 。
摘要
Log4j 2(2.4)提供了多種方法來避免在未實際記錄消息時對日志語句的性能造成影響。
翻譯自: https://www.javacodegeeks.com/2015/10/better-performing-non-logging-logger-calls-in-log4j2.html
總結
以上是生活随笔為你收集整理的在Log4j2中更好地执行非日志记录器调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 激战2电脑cpu(激战2高配电脑)
- 下一篇: 测试双重图案