2008-09-09 8 views
50

Als Teil einer Fehlerbehandlung in unserem Produkt möchten wir einige Stack-Trace-Informationen ausgeben. Wir stellen jedoch fest, dass viele Benutzer einfach einen Screenshot des Fehlermeldungsdialogs erstellen, anstatt uns eine Kopie des vollständigen Berichts aus dem Programm zu senden, und daher möchte ich in diesem Dialog einige minimale Stack-Trace-Informationen zur Verfügung stellen.Druckstack-Trace-Informationen von C#

Eine .NET-Stack-Trace auf meinem Rechner sieht wie folgt aus:

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) 
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) 
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize) 
at System.IO.StreamReader..ctor(String path) 
at LVKWinFormsSandbox.MainForm.button1_Click(Object sender, EventArgs e) in C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36 

Ich habe diese Frage:

Das Format sieht dies sein:

at <class/method> [in file:line ##] 

jedoch die bei und in Keywords, ich nehme an, diese werden lokalisiert, wenn sie, sagen wir, eine norwegische .NET-Laufzeit i anstelle der englischen habe ich installiert.

Gibt es eine Möglichkeit für mich, diese Stack-Trace in einer Sprache-Neutral-Art zu trennen, so dass ich nur die Datei und Zeilennummer für die Einträge anzeigen kann, die dies haben?

Mit anderen Worten, würde ich diese Informationen aus dem obigen Text mag:

C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36 

Jede Beratung Sie wird hilfreich sein, geben. anstelle einer Zeichenfolge ein Stacktrace-Objekt zu erhalten, indem er sagte

var trace = new System.Diagnostics.StackTrace(exception); 

Sie können dann schauen Sie sich die Bilder selbst, ohne sich auf den Rahmen der Formatierung

+1

Ich wünschte, jemand das Parsen Antwort auf diese gegeben hätte, wie ich mit protokollierten Strings aus beliebigen Anwendungen arbeiten bin und Ich hatte wirklich gehofft, ein paar Details dazu zu bekommen.Wenn Sie die Quelle des StackTrace kontrollieren, haben Sie in der Tat die richtige Antwort gewählt :) – TheXenocide

Antwort

70

sollten Sie in der Lage sein.

Siehe auch: StackTrace reference

+0

Oooh, schön, das wusste ich nicht! Ich werde mich definitiv darum kümmern. –

+0

Im Freigabemodus sind Sie immer noch in der Lage, Stack-Trace einer Ausnahme genau zu bekommen? – erdogany

+0

Ich serialisieren ** Ausnahme ** in Datei. 'SerializationHelper.Serialize (@" c: \ temp \ ConfigurationErrorsExceptions.ser ", ex);' Wenn ich aus der Datei deserialize 'var exception = SerializationHelper.Deserialize (@" ConfigurationErrorsExceptions.ser ");' *** Trace *** ist _nicht available_ 'var trace = new System.Diagnostics.StackTrace (Ausnahme als Exception);' the ** FrameCount ** ist 0 – Kiquenet

0

Als Alternative, log4net, obwohl gefährlich potenziell mir bessere Ergebnisse als System.Diagnostics gegeben hat. Grundsätzlich haben Sie in log4net eine Methode für die verschiedenen Protokollebenen mit jeweils einem Exception-Parameter. Wenn Sie die zweite Ausnahme übergeben, wird der Stack-Trace auf den Appender gedruckt, den Sie konfiguriert haben.

Beispiel: Logger.Error("Danger!!!", myException);

Der Ausgang, je nach Konfiguration, sieht etwas wie

System.ApplicationException: Something went wrong. 
    at Adapter.WriteToFile(OleDbCommand cmd) in C:\Adapter.vb:line 35 
    at Adapter.GetDistributionDocument(Int32 id) in C:\Adapter.vb:line 181 
    ... 
+0

Könnten Sie erklären, was Sie damit meinen, dass log4net "potentiell gefährlich" ist? –

+0

Ich weiß nicht genau, was Oglester meinte, aber ich weiß, dass stackoverflow.com einige Deadlock-Probleme hatte, weil log4net Ausnahmen zu einer Datenbank protokollierte. Ich hatte persönlich keine Probleme, aber ich behalte es einfach und halte mich an Textdateien. –

+0

Wenn Sie Ihre Verweise nicht ordnungsgemäß verwalten, führt dies zu einem Speicherverlust. Die Website, an der ich vor einiger Zeit gearbeitet habe, nutzt log4net ausgiebig (Rolling Files). Da log4net-Verweise auf eine Datei (unsicher) verweisen, müssen Sie sicherstellen, dass log4net-Verweise aufgeräumt oder auf ein Minimum beschränkt bleiben. –

27

Hier ist der Code ich diese

ohne Ausnahme verwenden zu tun
public static void LogStack() 
{ 
    var trace = new System.Diagnostics.StackTrace(); 
    foreach (var frame in trace.GetFrames()) 
    { 
    var method = frame.GetMethod(); 
    if (method.Name.Equals("LogStack")) continue; 
    Log.Debug(string.Format("{0}::{1}", 
     method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, 
     method.Name)); 
    } 
} 
+0

Sie würden denken, dass dies irgendwo in Funktionalität eingebaut sein würde, da der Ausnahmebehandler es nativ tut. –

18

Nur um sicher Dies ist eine 15-sekündige Kopier-Einfüge-Antwort:

static public string StackTraceToString() 
{ 
    StringBuilder sb = new StringBuilder(256); 
    var frames = new System.Diagnostics.StackTrace().GetFrames(); 
    for (int i = 1; i < frames.Length; i++) /* Ignore current StackTraceToString method...*/ 
    { 
     var currFrame = frames[i]; 
     var method = currFrame.GetMethod(); 
     sb.AppendLine(string.Format("{0}:{1}",      
      method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, 
      method.Name)); 
    } 
    return sb.ToString(); 
} 

(basierend auf Antwort Lindholm)

+3

Danke dafür. Beachten Sie, dass Sie sb.AppendLine (...) verwenden können, um das Festcodieren des Zeilenendes zu vermeiden. –

+0

wahr. aktualisiert... –

8

Oder gibt es noch kürzere Version ..

Console.Write(exception.StackTrace);