2010-04-04 57 views
5
try 
{ 
    // Code 
} 
catch (Exception ex) 
{ 
    Logger.Log("Message", ex); 
    throw; 
} 

在庫的情況下,我是否應該記錄異常?我應該拋出它並允許應用程序記錄它嗎?我擔心的是,如果我在庫中記錄異常,會有很多重複項(因爲庫層會記錄它,應用程序層會記錄它,以及其間的任何內容),但是如果我沒有記錄它圖書館,它很難追蹤錯誤。有沒有最佳做法?何時登錄異常?

回答

3

我不會記錄一個異常,我不會做任何事情 - 即,如果它只是通過異常處理程序,如在您的示例中。正如你已經提到的,這增加了很多噪音,但不一定有幫助。最好在實際操作的地方記錄它,或者在庫的情況下記錄在它轉換到用戶代碼的邊界。

也就是說,我總是嘗試登錄我拋出異常的位置以及觸發異常的條件。這對於確定例外的原因更有用。再加上,如果遇到的情況足夠糟糕,可以保證拋出異常,我想說它也可以保證花費處理器時間註銷'爲什麼'。

1

您應該記錄它並將其扔掉,以便應用程序可以將其記錄下來。特別是如果它是一個庫,你應該記錄它,因爲你不應該不應該假設應用程序肯定會記錄它!(它可能會也可能不會)。

2

我傾向於更傾向於將日誌記錄提升到最高級別的客戶端,或者允許客戶端啓用/禁用日誌記錄,這可能是通過向庫提供TextWriter來實現的,在沒有權限寫入其日誌的環境中。

我更喜歡登錄更高級別的原因是更高級別擁有更多上下文信息,並且可能知道更合適的方式來報告/記錄這些錯誤。由於異常現在有異常的堆棧跟蹤信息,所以我認爲當發生異常時,通過立即登錄就不會獲得太多收益。但是,必須注意轉換爲其他類型異常的異常,因此,如果要在處理異常時轉換異常,請始終使用InnerException,以便保留關於錯誤來源的所有信息。

編輯:當然,這種哲學只適用於遵循我的其他哲學的環境:永遠不要忽視例外。如果客戶端或某個中間層拋出異常,那麼您還有其他問題,並且可能需要至少將您的異常日誌默認爲即使客戶端不負責任也會生成的某個輸出。

1

日誌異常也可能是一種調試應用程序的方法。

1

使用log4net。認真。

通過使用這樣一個標準和無處不在的庫,你從那些花了很長時間思考這個問題的人那裏得到了指導。解決方案是大多數日誌記錄庫都有幾個日誌記錄級別。

在log4net的,例如我可以做

ILog log = LogManager.GetLogger("some logger"); 
log.Debug("some debugging info"); 
log.Info("some message meaningful in the domain"); 
log.Warn("something might be occurring that merits your attention"); 
log.Error("Everything just went to hell") 

應用程序管理員就可以設置不同級別的日誌記錄,他希望看到的。甚至可以允許他在運行時更改此配置。事實上,使用log4net等強大的日誌記錄庫,您可以將來自不同來源的不同日誌記錄級別指向不同的appender。例如,您可以使用一個滾動文件,其中包含存儲在硬盤上的所有日誌消息,所有信息,警告和錯誤消息都不會源自數據訪問層,並且會將所有錯誤發送到數據庫給你通過電子郵件。

我認爲你所描述的東西在「調試」日誌級別下很明顯。

你當然可以自己實現日誌級別,但如果有人使用你的庫有興趣看到所有的調試信息,他們將不得不學習你的系統,除了他們正在使用的任何一個。更好地標準化。

所以最佳實踐:

  1. 使用不同的日誌記錄級別。
  2. 不要推出你自己的日誌框架,使用log4net(這真的是在這個時代相當標準)或至少微軟的entlib logging block