2010-11-22 112 views
3

是否可以使用NLog記錄異常的屬性?記錄異常屬性

例如,SocketException具有屬性,如ErrorCode,HResult,NativeErrorCode等僅針對此類異常的屬性。可以在沒有明確記錄的情況下記錄它們(即不使用Log(e.ErrorCode))並僅使用代碼中的ErrorException?默認Exception layout renderer只是在異常時調用ToString。

回答

3

我不知道這是一個非常好的主意,但您可以編寫自己的LayoutRenderer。爲了保持簡單,我只寫了一個從ExceptionLayoutRenderer繼承並覆蓋Append方法的代碼。

[LayoutRenderer("ExtendedException")] 
    public class ExtendedExceptionLayoutRenderer : ExceptionLayoutRenderer 
    { 
     protected override void Append(System.Text.StringBuilder builder, LogEventInfo logEvent) 
     { 
      base.Append(builder, logEvent); 

      var exception = logEvent.Exception; 
      if (exception is SocketException) 
      { 
       var sockException = (SocketException) exception; 
       builder.Append(sockException.ErrorCode).Append(" ").Append(sockException.SocketErrorCode); 
      } 
     } 
    } 

SocketException的處理不是很複雜。我確信有更好的方法,但它顯示了你如何做到這一點。

要激活,你必須調整你的配置是這樣的:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <extensions> 
     <add assemblyFile="YourAssembly.dll"/> 
    </extensions> 

    <targets> 
     <target name="console" xsi:type="Console" layout="${extendedexception} ${message}"/> 
    </targets> 

    <rules> 
     <logger name="*" minlevel="Debug" writeTo="console" /> 
    </rules> 
</nlog> 

編輯

好吧,我不知道你想要的功能,爲每個有例外它自己的特性。如果只有少數其他人感興趣,則可以添加更多if(例外是YourExceptionType)並調整您感興趣的屬性。 更通用的方法是使用反射記錄所有已定義的屬性在例外。

[LayoutRenderer("ExtendedException")] 
    public class ExtendedExceptionLayoutRenderer : ExceptionLayoutRenderer 
    { 
     protected override void Append(System.Text.StringBuilder builder, LogEventInfo logEvent) 
     { 
      var exception = logEvent.Exception; 
      var type = exception.GetType(); 
      var properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); 

      var logEntries = new SortedDictionary<string, string>(); 

      foreach (var property in properties) 
      { 
       var name = property.Name; 
       var value = property.GetValue(exception, null).ToString(); 
       logEntries.Add(name, value); 
      } 

      foreach (var entry in logEntries) 
      { 
       builder.AppendFormat("{0}: {1} ", entry.Key, entry.Value); 
      } 

      base.Append(builder, logEvent); 
     } 
    } 

這將按字母順序將異常類型上聲明的每個屬性都添加到日誌輸出中。

0

序列化異常並記錄結果流?

1

我不熟悉NLog,但可以在try/catch塊中捕獲異常,然後拋出一個新的自己類型的異常,覆蓋ToString以輸出您關心的新異常中的數據類型?

這樣做會在某種程度上破壞跟蹤,因此您可能必須在ToString輸出中包含來自原始異常的跟蹤信息,但這可能是一個簡單的解決方法。

我的另一個想法是擴展和重寫SocketException的ToString,但我不相信在C#中是可能的。

+0

這意味着我需要爲每個暴露額外屬性的異常類執行此操作。 SocketException只是其中之一。我在尋找更一般的東西。感謝您的回答。 – Giorgi 2010-11-22 18:28:20

+0

@Giorgi - 抱歉,沒有收到。你可以用反射來實現這個相同的策略來迭代所有類型的拋出異常的所有屬性....這開始感覺像一個骯髒的黑客,雖然... – userx 2010-11-23 00:27:56