2010-11-22 5 views
3

Ist es möglich, Eigenschaften der Ausnahme mit NLog zu protokollieren?Eigenschaften der Protokollierungsausnahme

Zum Beispiel hat SocketException Eigenschaften wie ErrorCode, HResult, NativeErrorCode usw., die nur für diesen Typ von Ausnahmen gelten. Es ist möglich, sie zu protokollieren, ohne sie explizit zu protokollieren (d. H. Ohne Log(e.ErrorCode) zu verwenden) und nur ErrorException aus dem Code zu verwenden? Der Standardwert Exception layout renderer ruft nur ToString für die Ausnahme auf.

Antwort

3

Ich weiß nicht, ob es eine sehr gute Idee ist, aber Sie können Ihren eigenen LayoutRenderer schreiben. Um es einfach zu halten, habe ich nur einen geschrieben, der von ExceptionLayoutRenderer erbt und die Append-Methode überschrieben hat.

[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); 
      } 
     } 
    } 

Die Handhabung der SocketException ist nicht sehr anspruchsvoll. Ich bin mir sicher, dass es einen besseren Weg gibt, aber es zeigt, wie Sie es tun können.

zu aktivieren, dass Sie Ihre Konfiguration wie folgt anpassen:

<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> 

bearbeiten

Ok, ich war nicht bewusst, dass Sie diese Funktion für jede Ausnahme wollen, dass es seine eigene Eigenschaften . Wenn es nur wenige andere gibt, an denen Sie interessiert sind, können Sie einfach weitere if (Ausnahme: YourExceptionType) hinzufügen und die gewünschten Eigenschaften anpassen. Ein allgemeinerer Ansatz besteht darin, Reflektion zum Protokollieren aller definierten Eigenschaften zu verwenden auf die Ausnahme.

[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); 
     } 
    } 

Dadurch wird jede Eigenschaft, die für den Ausnahmetyp deklariert ist, in alphabetischer Reihenfolge zur Protokollausgabe hinzugefügt.

+1

Ich tippte genau das Gleiche. Wenn NLog die Funktion direkt bereitstellt, ist mir dies nicht bekannt. Wenn Sie diese Informationen benötigen (oder wollen) und NLog diese nicht "kostenlos" zur Verfügung stellt, müssen Sie etwas tun, wie es @treze vorschlägt. – wageoghe

+0

In diesem Fall muss ich Renderer für jeden Typ von Ausnahme erstellen, der seine eigenen Eigenschaften hat: Win32Exception, WebException, HttpException und so weiter. – Giorgi

+0

@Giorgi - Sie können dies mit nur einem Layout-Renderer mit Reflektion tun. Siehe meinen bearbeiteten Post. – treze

0

Seriennummer serialisieren und den resultierenden Stream protokollieren?

1

Ich bin nicht vertraut mit NLog, aber ist es möglich, die Ausnahme in einem try/catch-Block zu fangen und dann eine neue Ausnahme des eigenen Typs zu werfen, ToString überschreiben, um die Daten auszugeben, die Sie in Ihrer neuen Ausnahme interessieren Art?

Dies würde die Traceerstellung etwas unterbrechen, also müssten Sie wahrscheinlich die Trace-Informationen aus der ursprünglichen Ausnahme in Ihre ToString-Ausgabe einbeziehen, aber es könnte eine einfache Lösung sein.

Mein anderer Gedanke war, ToString von SocketException zu erweitern und zu überschreiben, aber ich glaube nicht, dass das in C# möglich ist.

+0

Das bedeutet, dass ich es für jede Ausnahmeklasse tun muss, die zusätzliche Eigenschaften zur Verfügung stellt. SocketException ist nur eine davon. Ich suche nach etwas allgemeinerem. Danke für deine Antwort. – Giorgi

+0

@Giorgi - Sorry, habe das nicht verstanden. Du könntest die gleiche Strategie mit Reflektion implementieren, um alle Eigenschaften von throw-Ausnahmen aller Typen zu durchlaufen ... das fängt an, sich wie ein schmutziger Hack zu fühlen ... – userx

Verwandte Themen