logger打印日志時加if (logger.isInfoEnabled())/if (logger.isDebugEnabled())


為什么記錄debug和info日志前要加個判斷?其實原因很簡單:提高效率!如上代碼所示,在記錄日志時進行了字符串拼接,要知道這是會消耗一定資源的。假如當前log日志級別是error,則debug和info是不會被輸出的,如果加了if判斷則log.debug/info中的字符串拼接就不會執行,自然提高了效率。

些人不明白為什么要這樣寫。有些人認為這樣是為了能夠控制日志的輸出,對於下面這行代碼:

 

[java]  view plain  copy
 
  1. logger.debug(message);  

他們的看法是:如果這樣寫的話,就算你把日志級別調整為info, 這里也會輸出日志。

其實,在debug()方法里面,就已經叛斷了日志的級別。以下是isDebugEnabled()的源碼:

[java]  view plain  copy
 
  1. public boolean isDebugEnabled() {  
  2.     if(repository.isDisabled( Level.DEBUG_INT))  
  3.         return false;  
  4.     return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());  
  5. }  

以下是debug()的源碼:

 

[java]  view plain  copy
 
  1. public void debug(Object message) {  
  2.     if(repository.isDisabled(Level.DEBUG_INT))  
  3.         return;  
  4.     if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {  
  5.         forcedLog(FQCN, Level.DEBUG, message, null);  
  6.     }  
  7. }  


 我們可以看到,在debug()方法里做了跟isDebugEnabled()方法一樣的判斷。

在這里,我們不禁會想,那我們凡是要輸日志的地方,都不判斷isDebugEnabled,直接調debug方法,不更省事嗎?

官方的說法是:出於效率考慮,看具體情況而定.

我們來看下面一行代碼:

 

[java]  view plain  copy
 
  1. logger.debug("The money is " + getTotalMoney());  


假設我們的日志級別設置為info,那這句話不會輸出日志,但這個方法還是會調用。要調用這個方法,必須提供參數。getTotalMoney()方法返回的結果就是參數的一部分。假設getTotalMoney()要執行10秒鍾,10秒鍾后,進入到debug()方法里,碰到了第一個判斷:

 

[cpp]  view plain  copy
 
  1. if(repository.isDisabled(Level.DEBUG_INT))  
  2.     return;  


在這里就返回了。結果是日志雖然沒有輸出,卻花費了10秒鍾來構造參數。很顯然這里得不償失的。盡管實際應用中幾乎不可能有這種花10秒鍾來構造這樣一個參數的情況,但如果並發數大的話,這樣寫還是會影響系統的性能的。這個時候,就應該寫成:

 

[java]  view plain  copy
 
  1. if(logger.isDebugEnabled()){  
  2.     logger.debug("The money is " + getTotalMoney());  
  3. }  


如果debug的參數很簡單的話,也可以直接寫 logger.debug(message)的。官方的說法,執行一次logger.isDebugEnabled()這樣的判斷花費的時間大概是寫日志時間的萬分之一.雖然這個比例很小,

在小系統看不出差距,但如果是高並發的系統下,少執行一句代碼能明顯減小服務器的壓力。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM