記事

日誌級別的選擇:Debug、Info、Warn、Error還是Fatal


 軟件中總免不了要使用諸如 Log4net, Log4j, Tracer 等東東來寫日誌,不管用什麼,這些東東大多是大同小異的,一般都提供了這樣5個日誌級別:
    × Debug
    × Info
    × Warn
    × Error
    × Fatal
        一個等級比一個高,但是在具體開發中,關於應該如何選擇適應的等級,卻沒有找到好的文章進行說明。記錄一下自己的一些看法,以便日後使用吧。

=== Debug ===
        這個級別最低的東東,一般的來說,在系統實際運行過程中,一般都是不輸出的。


        因此這個級別的信息,可以隨意的使用,任何覺得有利於在調試時更詳細的瞭解系統運行狀態的東東,比如變量的值等等,都輸出來看看也無妨。


        當然,在每一個 Debug 調用之前,一定要加上 If 判斷。

=== Info ===
        這個應該用來反饋系統的當前狀態給最終用戶的,所以,在這裏輸出的信息,應該對最終用戶具有實際意義,也就是最終用戶要能夠看得明白是什麼意思才行。


        從某種角度上說,Info 輸出的信息可以看作是軟件產品的一部分(就像那些交互界面上的文字一樣),所以需要謹慎對待,不可隨便。

=== Warn、Error、Fatal ===
        警告、錯誤、嚴重錯誤,這三者應該都在系統運行時檢測到了一個不正常的狀態,他們之間的區別,要區分還真不是那麼簡單的事情。我大致是這樣區分的:


        所謂警告,應該是這個時候進行一些修復性的工作,應該還可以把系統恢復到正常狀態中來,系統應該可以繼續運行下去。


        所謂錯誤,就是說可以進行一些修復性的工作,但無法確定系統會正常的工作下去,系統在以後的某個階段,很可能會因爲當前的這個問題,導致一個無法修復的錯誤(例如宕機),但也可能一直工作到停止也不出現嚴重問題。

        所謂Fatal,那就是相當嚴重的了,可以肯定這種錯誤已經無法修復,並且如果系統繼續運行下去的話,可以肯定必然會越來越亂。這時候採取的最好的措施不是試圖將系統狀態恢復到正常,而是儘可能地保留系統有效數據並停止運行。

        也就是說,選擇 Warn、Error、Fatal 中的具體哪一個,是根據當前的這個問題對以後可能產生的影響而定的,如果對以後基本沒什麼影響,則警告之,如果肯定是以後要出嚴重問題的了,則Fatal之,拿不準會怎麼樣,則 Error 之。

=== 一些疑惑 ===
        不過在實際使用中,基於上面的這種考慮,也還是有一些具體問題。最常見的就是要在最終產品中將輸出日誌打開到那種級別纔算好呢?


        例如在應用中有一個輸出窗口,一些系統狀態信息將被輸出到這個輸出窗口中。因爲 Info 的級別是如此之低,所以爲了讓用戶能夠看到有效的輸出信息,必須將日誌級別開放到 Info 級別。但是 Warn 的級別比 Info 要高,所以用戶不得不被迫看到一些 Warn 的信息。而我們其實已經假定,Warn 信息其實並不影響系統的正常運行,這一般只代表系統中存在一些還沒有被發現或者修改的小 Bug。這些 Warn 信息會讓最終用戶困惑甚至恐慌,系統發出警告了,該怎麼辦?

        個人觀點,Info 的級別應該比 Warn 更高才對,Warn 信息和 Debug 一樣,應該在產品測試和調試時使用,而 Info、Erro 以及 Fatal 則在產品發佈後需要繼續使用。

        目前我所採用的解決方法是,對於 Warn、Error、Fatal 都添加一個相應的系統斷言,這樣,可以保證當發生這種問題時,在調試階段,可以立即得到提示。在軟件發佈以後,這些信息也能被記錄到日誌文件中去。

        

Java代碼  收藏代碼
  1. log.Warn("message");  
  2. System.Diagnostics.Debug.Fail("警告""message");  

 
        Debug.Fail 將導致編譯爲 Debug 輸出時,會彈出一個消息警告窗口,這可保證在測試、調試階段不漏過任何一個潛在的錯誤。而在發佈時,Release 編譯的輸出不會包括 Debug 語句,這就不會打擾最終用戶,而錯誤信息仍然能通過 log 記錄到日誌中。


log4j.rootLogger=debug, Console, info,error,debug  
#log4j.rootLogger=debug, Console, info,error,debug  
#Console  
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.Console.layout=org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n  
  
### 保存debug信息到單獨文件 ###  
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender  
log4j.appender.debug.File=G:/logs/debug.log  
log4j.appender.debug.Append = true  
log4j.appender.debug.Threshold = DEBUG  
log4j.appender.debug.layout=org.apache.log4j.PatternLayout  
log4j.appender.debug.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n  
  
### 保存info信息到單獨文件 ###  
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender  
log4j.appender.info.File=G:/logs/info.log  
log4j.appender.info.Append = true  
log4j.appender.info.Threshold = INFO  
log4j.appender.info.layout=org.apache.log4j.PatternLayout  
log4j.appender.info.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n  
   
### 保存異常信息到單獨文件 ###  
log4j.appender.error = org.apache.log4j.DailyRollingFileAppender  
log4j.appender.error.File =G:/logs/error.log  
log4j.appender.error.Append = true  
log4j.appender.error.Threshold = ERROR  
log4j.appender.error.layout = org.apache.log4j.PatternLayout  
log4j.appender.error.layout.ConversionPattern = %d [%t] %-5p [%c] - %m%n  
  
#Project default level  
log4j.logger.com.as.resource = INFO  
log4j.logger.org.springframework.web = INFO  
  
#DEBUG  
log4j.logger.java.sql.Connection = DEBUG  
log4j.logger.java.sql.Statement = DEBUG  
log4j.logger.java.sql.PreparedStatement = DEBUG  
log4j.logger.java.sql.ResultSet =DEBUG  
  
#mybatis  
log4j.logger.com.ibatis=DEBUG  
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG  
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG  
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG  


發佈了42 篇原創文章 · 獲贊 10 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章