2009-11-09 72 views
1

到現在爲止,我記錄了錯誤消息和異常的堆棧跟蹤。但是,如果我不記錄try塊中使用的所有變量,我認爲這樣做不是很有用。如果我可以看到try塊中使用的所有變量,我想我會更好地瞭解導致異常的原因,並且可以避免它再次發生。當發生異常時記錄什麼

你們是怎麼登錄的?

謝謝

回答

4

主要我們記錄錯誤消息和堆棧跟蹤。我們還會在日誌中添加註釋以說明發生這種情況的可能原因。這些消息通常就像「如果它在這裏失敗,用戶會話未設置,並且可能由於會話重置而發生。」通常這些信息是讓我們朝着正確方向尋找的東西。

如果您的try catch塊太大而無法做到這一點,我會考慮將其分離出來,以便更小塊。如果你不想這樣做,那麼我會開始爲不同類型的異常設置不同的catch塊。

catch(FileNotFoundException ex) 
{} 
catch(Exception regularException) 
{} 

這樣你就可以定製任何額外的信息,該類型的異常,並有一種普遍的例外作爲最後一個catch塊,以確保東西並不意外逃脫。

+0

這是一個好主意。我會記錄一條自定義錯誤消息。但是,如果我的try塊太大,有很多事情可能會出錯,並且我只有一個捕獲「System.Exception」的catch塊。如何區分自定義錯誤消息,因爲如果錯誤消息顯示「對象未設置爲實例...」,我們無法知道其中有多少個對象爲空...... 謝謝 – iJK 2009-11-09 14:48:39

+0

酷感謝:-) – iJK 2009-11-09 15:11:16

+0

@ iHeartDucks:如果您有代碼可能出現多個錯誤,請將多個try/catch塊放置在可能會出錯的行的周圍。然後你可以定製你想要的信息。 – 2009-11-09 15:12:09

0

一般而言,我只記錄異常消息和堆棧跟蹤,並嘗試記錄足夠的調試信息,以便我可以確定上下文中發生了什麼。通常這是綽綽有餘的細節來弄清楚出了什麼問題。

在我無法弄清楚異常情況如何發生的情況下,我添加了適用變量值的附加調試日誌記錄。當然,這僅適用於應用程序,並且可以在需要時臨時換出程序集。如果沒有這種類型的可訪問性,那麼你可能想看看Gibraltar。它提供了豐富的調試信息,可以從遠程客戶端發送並具有各種精美的表單來查看它。

1

我總是會試圖記錄方法中的所有內容,主要是因爲將來維護代碼的巨大維護開銷。

此外,您可能必須確保您的日誌記錄代碼具有上下文感知能力,即如果您使用嵌套在對象中的屬性,則日誌記錄代碼將需要了解如何在日誌期間獲取這些變量,以及這你必須確保記錄器可能做出的任何請求不會影響任何事情的狀態,或者它不會代表實際狀態。

爲什麼不努力在方法開始時驗證參數,然後在需要的地方對代碼進行空檢查?

+0

我會驗證所有輸入(在客戶端和服務器上)。是的,我同意在記錄對象的屬性時必須小心。我想,這只是我想知道發生的那些情況以及爲什麼在採取n個預防措施後出現錯誤。 – iJK 2009-11-09 14:54:04

5

正如其他人所說,在記錄異常時,我通常會記錄exception.ToString(),它通常只包含消息,堆棧跟蹤和內部異常。

但是在System.Exception上定義的屬性經常被遺忘,但可能是您正在尋找的屬性。它屬於IDictionary Data屬性。在該字典中,您可以放置​​任何您想要的東西,然後在記錄異常時使用它。

這裏是一個越野車的功能,使用它另外一個,並且無論是否存在uncatched異常棧展開時調用方法的簡單的例子:

public static int BuggyFoo(int notZeroPlease) 
{ 
    return 5/notZeroPlease; 
} 

public static int UseBuggyFoo(int userInput) 
{ 
    var myValue = userInput >> 2; 
    try 
    { 
     var foo = BuggyFoo(myValue); 
     return (foo + 5); 
    } 
    catch (Exception e) 
    { 
     e.Data["userInput"] = userInput; 
     e.Data["myValue"] = myValue; 
     throw; 
    } 
} 

public static void Application_OnError(Exception e) 
{ 
    var sb = new StringBuilder(); 
    foreach (var k in e.Data.Keys) 
    { 
     sb.AppendFormat("Data[{0}] = {1}\n", k, e.Data[k]) 
    } 
    Utilities.Logger.Log(sb.ToString(), e); 
} 

但這應該適量使用..否則(如果你的代碼是越野車)你會有巨大的日誌文件!

祝你好運!

編輯: 如果你不知道這一點Application_OnError()方法,這裏是一個可能的例證:

public static void Application_OnError(Exception e) 
{ /* ... */ } 

public static void Main() 
{ 
    try 
    { 
     /* ... */ 
    } 
    catch (Exception e) 
    { 
     Application_OnError(e); 
    } 
} 

如果要創建一個Web應用程序,使用ASP.NET,讓我們說,那麼你應該已經有一個Application_OnError方法在這種情況下被調用。

+0

是的,我也使用字典對象。我認爲結合你的答案+凱文的答案是一條路。 – iJK 2009-11-09 15:18:29

0

偶爾,我會記錄內部異常以及主要異常消息。這可以提供更具體的異常信息並允許更輕鬆的調試。

0

我有一個對象,我稱之爲'UserAction',每當用戶以某種方式與UI進行交互時,在列表中推入另一個用戶活動,例如「clicked x」或「將p從x拖動到y」。它還具有諸如日期/時間,用戶名等信息。當發生異常時,軟件會自動發送電子郵件通知異常消息,堆棧跟蹤和UserAction日誌的轉儲。試圖重現問題可能會非常有幫助。

我通常在用戶有機會到我的辦公室之前知道問題是什麼。

相關問題