2017-04-07 631 views
3

我想在調試日誌中編寫一些日誌,這些日誌在具有信息日誌級別的生產日誌中將不可用。那麼這個額外的調試日誌將如何影響性能?我的意思是如果我們在INFO中設置日誌級別,記錄器必須檢查日誌級別是什麼,並發現log.debug需要被忽略。那麼額外的日誌級別檢查是否會影響性能?在部署時是否有任何刪除log.debug()語句的自動方法?我的意思是在開發期間,log.debug將在那裏,我們可以調試。但在生產部署期間,automagical機制將刪除所有log.debug()消息。我不確定這些是否可能。如果不是那麼好 - C'est la vie!log.debug是否會降低性能

+1

當然,它會影響性能。問題在於它會如何影響性能。答案是,這取決於你記錄什麼,因爲PARAMS到'log'仍將即使沒有日誌輸出評價。解決此問題的方法是針對一個靜態變量的檢查,然後可以優化掉來包裝你的日誌報表,或進入一個記錄塊之前檢查日誌級別。問題是它是否值得。 –

回答

2

那麼這個額外的調試日誌將如何影響性能呢?

爲記錄儀盤I/O調用(假設你正在寫文件系統),絕對不建議在生產環境DEBUG日誌級別它會影響應用程序的性能。

是否有任何automagical方式在部署時刪除log.debug()語句 ?

沒有,是去除log.debug()報表沒有神奇的方式,但是當你設置日誌記錄級別爲INFO,那麼只要你是不是做重的計算,同時傳遞參數給debug()方法,它應該沒事的。例如,如果您有記錄級別設置爲INFO,並假定你已經得到了空兩個記錄器在你的代碼

logger.debug(" Entry:: "); //this logger is fine, no calculations 
//Below logger, you are doing computations to print i.e., calling to String methods 
logger.debug(" Entry : product:"+product+" dept:"+dept);//overhead toString() calls 

我建議使用slf4j,這樣就可以避免被第二記錄計算開銷

//Below logger product and dept toString() NOT invoked 
logger.debug(" Entry : product:{} dept{}", product, dept); 

一個更重要的一點是,與SLF4J只是一個抽象:如下圖所示使用{}(其中使用它的MessageFormatter與實際值替換)您可以在任何日誌框架之間切換,您可以在here以下看看下面的文本。

的簡單的日誌門面爲Java(SLF4J)用作一個簡單的門面 或抽象的各種日誌框架(例如java.util.logging中, 的logback,log4j的),允許最終用戶在所希望的記錄堵塞 框架在部署時。

+0

難道我們不能使用具有相同的特徵,因爲sl4j的log4j2? – user1539343

+0

是的,它是你的,要麼log4j2或SLF4J是(如上所示)相比log4j1.x避免'DEBUG'開銷肯定更好的選擇 – developer

1

你可以用你的「調試」語句調用isDebugEnabled()

if (log.isDebugEnabled()) { 
    log.debug("my debug statement"); 
} 

同樣,包住「信息」語句調用isInfoEnabled()

的想法這樣做背後檢查日誌級別是否被啓用是一種廉價(固定成本)操作。生成正在記錄的語句的成本取決於您在做什麼。

1

檢查日誌記錄級別的開銷是非常少的,幾乎可以忽略。啓用調試日誌時,您會看到對性能的重大影響。這種影響取決於您寫入日誌的數據量,存儲量(如果您的存儲是固態硬盤,與使用正常磁盤時的性能相比,性能降低幅度較小),則有多少線程會寫入日誌(自只有一個線程可以立即寫入文件,所有其他線程必須等待,這是一個順序過程)。我已經提到了三個,但是還有更多的因素決定了日誌記錄對應用程序性能的影響。

要回答你的第二個問題是沒有自動的方式從你的代碼中刪除調試語句。

2

你可以通過你如何編寫記錄語句儘量減少這種。如果你寫

Object a = .... 
log.debug("I have an a: " + a); 

然後不管你使用的參數的日誌框架必須在調試功能運行之前進行評估。這意味着,即使你在INFO水平,你付出呼籲atoString和構建參數字符串的性能開銷。如果您改爲寫例如(這取決於格式化你的日誌框架使用,該工程的log4j和SLF4J)

log.debug("I have an a: {}", a); 

您不支付這筆費用,但只記錄器檢查您是否在調試模式是成本 - 除非你需要它,你不支付參數評估。

的另一件事是檢查你正在緩衝輸出(同樣,在SLF4J,有緩衝追加程序),這將最大限度地減少寫入。

1

,我想指出的另一種技術,往往在Android開發應用,是可以後期處理您的罐子裏取出電話,如調試。使用的工具通常是proguard。如果定義了呼叫作爲無副作用,它可以被優化,確保幾乎爲零的性能損失被刪除....它甚至應該是足夠聰明的優化掉你正在做的日誌信息的任何字符串建設。

https://www.guardsquare.com/en/proguard/manual/usage#assumenosideeffects