Update: Erweiterungen zu System.Diagnostics mit einigen der fehlenden Listener, die Sie möglicherweise benötigen, finden Sie unter Essential.Diagnostics auf CodePlex ( http://essentialdiagnostics.codeplex.com/ ).
Frameworks
F: Welche Frameworks verwenden Sie?
A: System.Diagnostics.TraceSource, integriert in .NET 2.0.
Es bietet leistungsstarke, flexible und leistungsstarke Protokollierung für Anwendungen. Viele Entwickler sind sich jedoch seiner Funktionen nicht bewusst und nutzen sie nicht vollständig.
Es gibt einige Bereiche, in denen zusätzliche Funktionen nützlich sind oder manchmal vorhanden sind, die jedoch nicht gut dokumentiert sind. Dies bedeutet jedoch nicht, dass das gesamte Protokollierungsframework (das erweiterbar ausgelegt ist) weggeworfen und wie einige gängige Alternativen vollständig ersetzt werden sollte (NLog, log4net, Common.Logging und sogar EntLib Logging).
Anstatt die Art und Weise zu ändern, in der Sie Ihrer Anwendung Protokollierungsanweisungen hinzufügen und das Rad neu erfinden, haben Sie das System.Diagnostics-Framework nur an den wenigen Stellen erweitert, an denen Sie es benötigen.
Mir scheint, die anderen Frameworks, sogar EntLib, leiden einfach unter dem Not Invented Here-Syndrom, und ich denke, sie haben Zeit damit verschwendet, die Grundlagen neu zu erfinden, die in System.Diagnostics bereits einwandfrei funktionieren (z. B. wie Sie Protokollanweisungen schreiben). anstatt die wenigen vorhandenen Lücken zu füllen. Kurz gesagt, verwenden Sie sie nicht - sie werden nicht benötigt.
Funktionen, die Sie möglicherweise nicht kennen:
- Die Verwendung von TraceEvent-Überladungen, die eine Formatzeichenfolge und Argumente annehmen, kann die Leistung verbessern, da Parameter als separate Referenzen beibehalten werden, bis Filter.ShouldTrace () erfolgreich war. Dies bedeutet, dass keine teuren Aufrufe von ToString () für Parameterwerte erfolgen, bis die vom System bestätigte Nachricht tatsächlich protokolliert wird.
- Mit dem Trace.CorrelationManager können Sie Protokollanweisungen zu derselben logischen Operation korrelieren (siehe unten).
- VisualBasic.Logging.FileLogTraceListener eignet sich zum Schreiben in Protokolldateien und unterstützt die Dateirotation. Obwohl im VisualBasic-Namespace, kann es in einem C # -Projekt (oder einem anderen Sprachprojekt) genauso einfach verwendet werden, indem einfach die DLL eingeschlossen wird.
- Wenn Sie EventLogTraceListener verwenden und TraceEvent mit mehreren Argumenten und einer leeren Zeichenfolge oder einer Zeichenfolge im Nullformat aufrufen, werden die Argumente direkt an EventLog.WriteEntry () übergeben, wenn Sie lokalisierte Nachrichtenressourcen verwenden.
- Das Service Trace Viewer-Tool (von WCF) ist nützlich, um Diagramme von aktivitätskorrelierten Protokolldateien anzuzeigen (auch wenn Sie WCF nicht verwenden). Dies kann wirklich dazu beitragen, komplexe Probleme zu beheben, bei denen mehrere Threads / Aktivitäten beteiligt sind.
- Vermeiden Sie Overhead, indem Sie alle Listener löschen (oder Default entfernen). Andernfalls übergibt Default alles an das Trace-System (und verursacht all diese ToString () - Overheads).
Bereiche, die Sie möglicherweise erweitern möchten (falls erforderlich):
- Datenbank-Trace-Listener
- Farbiger Konsolen-Trace-Listener
- MSMQ / Email / WMI-Trace-Listener (falls erforderlich)
- Implementieren Sie einen FileSystemWatcher, um Trace.Refresh für dynamische Konfigurationsänderungen aufzurufen
Sonstige Empfehlungen:
Verwenden Sie strukturierte Ereignis-IDs und führen Sie eine Referenzliste (z. B. dokumentieren Sie sie in einer Aufzählung).
Das Vorhandensein eindeutiger Ereignis-IDs für jedes (signifikante) Ereignis in Ihrem System ist sehr nützlich, um bestimmte Probleme zu korrelieren und zu finden. Es ist einfach, zu dem spezifischen Code zurückzukehren, der die Ereignis-IDs protokolliert / verwendet, und es kann einfach sein, Anleitungen für häufig auftretende Fehler bereitzustellen, z. B. Fehler 5178 bedeutet, dass Ihre Datenbankverbindungszeichenfolge falsch ist usw.
Ereignis-IDs sollten einer bestimmten Struktur folgen (ähnlich der in E-Mail und HTTP verwendeten Theorie der Antwortcodes), mit der Sie sie nach Kategorien behandeln können, ohne bestimmte Codes zu kennen.
Beispiel: Die erste Ziffer kann die allgemeine Klasse detaillieren: 1xxx kann für 'Start'-Operationen verwendet werden, 2xxx für normales Verhalten, 3xxx für Aktivitätsverfolgung, 4xxx für Warnungen, 5xxx für Fehler, 8xxx für' Stop'-Operationen, 9xxx für schwerwiegende Fehler, usw.
Die zweite Ziffer kann den Bereich detaillieren, z. B. 21xx für Datenbankinformationen (41xx für Datenbankwarnungen, 51xx für Datenbankfehler), 22xx für den Berechnungsmodus (42xx für Berechnungswarnungen usw.), 23xx für ein anderes Modul usw.
Mit zugewiesenen, strukturierten Ereignis-IDs können Sie diese auch in Filtern verwenden.
F: Wenn Sie die Ablaufverfolgung verwenden, verwenden Sie Trace.Correlation.StartLogicalOperation?
A: Trace.CorrelationManager ist sehr nützlich, um Protokollanweisungen in jeder Art von Multithread-Umgebung zu korrelieren (was heutzutage so ziemlich alles ist).
Sie müssen die ActivityId mindestens einmal für jede logische Operation festlegen, um eine Korrelation herzustellen.
Start / Stop und der LogicalOperationStack können dann für einen einfachen stapelbasierten Kontext verwendet werden. Bei komplexeren Kontexten (z. B. asynchronen Operationen) ermöglicht die Verwendung von TraceTransfer für die neue ActivityId (vor dem Ändern) die Korrelation.
Das Service Trace Viewer-Tool kann zum Anzeigen von Aktivitätsdiagrammen hilfreich sein (auch wenn Sie WCF nicht verwenden).
F: Schreiben Sie diesen Code manuell oder verwenden Sie dazu eine aspektorientierte Programmierung? Möchten Sie ein Code-Snippet freigeben?
A: Möglicherweise möchten Sie eine Bereichsklasse erstellen, z. B. LogicalOperationScope, die (a) den Kontext beim Erstellen einrichtet und (b) den Kontext beim Entsorgen zurücksetzt.
Auf diese Weise können Sie Code wie den folgenden schreiben, um Vorgänge automatisch zu verpacken:
using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
{
// .. do work here
}
Bei der Erstellung konnte der Bereich bei Bedarf zuerst ActivityId festlegen, StartLogicalOperation aufrufen und dann eine TraceEventType.Start-Nachricht protokollieren. Bei Entsorgen kann eine Stoppnachricht protokolliert und anschließend StopLogicalOperation aufgerufen werden.
F: Bieten Sie eine Form der Granularität für Trace-Quellen an? Mit WPF TraceSources können Sie sie beispielsweise auf verschiedenen Ebenen konfigurieren.
A: Ja, mehrere Trace-Quellen sind nützlich / wichtig, wenn die Systeme größer werden.
Während Sie wahrscheinlich alle Warnungen und höher oder alle Informationen und Nachrichten konsistent protokollieren möchten, wird für jedes System mit angemessener Größe das Volumen der Aktivitätsverfolgung (Start, Stopp usw.) und der ausführlichen Protokollierung einfach zu groß.
Anstatt nur einen Schalter zu haben, der alles ein- oder ausschaltet, ist es hilfreich, diese Informationen jeweils für einen Abschnitt Ihres Systems aktivieren zu können.
Auf diese Weise können Sie signifikante Probleme anhand der normalerweise protokollierten Protokollierung (alle Warnungen, Fehler usw.) lokalisieren und dann die gewünschten Abschnitte "vergrößern" und auf Aktivitätsverfolgung oder sogar Debug-Ebenen einstellen.
Die Anzahl der benötigten Ablaufverfolgungsquellen hängt von Ihrer Anwendung ab, z. B. möchten Sie möglicherweise eine Ablaufverfolgungsquelle pro Assembly oder pro Hauptabschnitt Ihrer Anwendung.
Wenn Sie eine noch feinere Steuerung benötigen, fügen Sie einzelne boolesche Schalter hinzu, um die spezifische Ablaufverfolgung mit hohem Volumen ein- und auszuschalten, z. B. Rohnachrichten-Dumps. (Oder es könnte eine separate Trace-Quelle verwendet werden, ähnlich wie bei WCF / WPF).
Möglicherweise möchten Sie auch separate Ablaufverfolgungsquellen für die Aktivitätsverfolgung im Vergleich zur allgemeinen (anderen) Protokollierung in Betracht ziehen, da dies die Konfiguration von Filtern genau nach Ihren Wünschen erleichtert.
Beachten Sie, dass Nachrichten auch dann über ActivityId korreliert werden können, wenn verschiedene Quellen verwendet werden. Verwenden Sie daher so viele, wie Sie benötigen.
Zuhörer
F: Welche Protokollausgaben verwenden Sie?
Dies kann davon abhängen, welche Art von Anwendung Sie schreiben und welche Dinge protokolliert werden. Normalerweise gehen verschiedene Dinge an verschiedenen Orten (dh mehrere Ausgänge).
Ich klassifiziere Outputs im Allgemeinen in drei Gruppen:
(1) Ereignisse - Windows-Ereignisprotokoll (und Ablaufverfolgungsdateien)
Wenn Sie beispielsweise einen Server / Dienst schreiben, empfiehlt es sich unter Windows, das Windows-Ereignisprotokoll zu verwenden (Sie haben keine Benutzeroberfläche, an die Sie Bericht erstatten können).
In diesem Fall sollten alle Ereignisse mit schwerwiegenden, Fehler-, Warn- und (Service-Level-) Informationen in das Windows-Ereignisprotokoll aufgenommen werden. Die Informationsebene sollte für diese Art von Ereignissen auf hoher Ebene reserviert sein, die Sie in das Ereignisprotokoll aufnehmen möchten, z. B. "Dienst gestartet", "Dienst gestoppt", "Mit Xyz verbunden" und möglicherweise sogar "Zeitplan initiiert". , "Benutzer angemeldet" usw.
In einigen Fällen möchten Sie möglicherweise das Schreiben in das Ereignisprotokoll zu einem integrierten Bestandteil Ihrer Anwendung machen und nicht über das Trace-System (dh das Schreiben von Ereignisprotokolleinträgen direkt). Dies bedeutet, dass es nicht versehentlich ausgeschaltet werden kann. (Beachten Sie, dass Sie immer noch dasselbe Ereignis in Ihrem Trace-System notieren möchten, damit Sie korrelieren können.)
Im Gegensatz dazu meldet eine Windows-GUI-Anwendung diese im Allgemeinen dem Benutzer (obwohl sie möglicherweise auch im Windows-Ereignisprotokoll protokolliert werden).
Ereignisse können auch verwandte Leistungsindikatoren haben (z. B. Anzahl der Fehler / Sek.), Und es kann wichtig sein, das direkte Schreiben in das Ereignisprotokoll, die Leistungsindikatoren, das Schreiben in das Ablaufverfolgungssystem und das Melden an den Benutzer so zu koordinieren, dass sie auftreten die selbe Zeit.
Wenn ein Benutzer zu einem bestimmten Zeitpunkt eine Fehlermeldung sieht, sollte es möglich sein, dieselbe Fehlermeldung im Windows-Ereignisprotokoll und dann dasselbe Ereignis mit demselben Zeitstempel im Ablaufverfolgungsprotokoll (zusammen mit anderen Ablaufverfolgungsdetails) zu finden.
(2) Aktivitäten - Anwendungsprotokolldateien oder Datenbanktabelle (und Trace-Dateien)
Dies ist die reguläre Aktivität, die ein System ausführt, z. B. Webseite, Börsenhandel, Bestellung, Berechnung usw.
Die Aktivitätsverfolgung (Start, Stopp usw.) ist hier nützlich (in der richtigen Granualität).
Außerdem wird häufig ein bestimmtes Anwendungsprotokoll verwendet (manchmal auch als Überwachungsprotokoll bezeichnet). Normalerweise ist dies eine Datenbanktabelle oder eine Anwendungsprotokolldatei und enthält strukturierte Daten (dh eine Reihe von Feldern).
Abhängig von Ihrer Anwendung kann es hier zu Unschärfen kommen. Ein gutes Beispiel könnte ein Webserver sein, der jede Anforderung in ein Webprotokoll schreibt. Ähnliche Beispiele können ein Nachrichtensystem oder ein Berechnungssystem sein, bei dem jeder Vorgang zusammen mit anwendungsspezifischen Details protokolliert wird.
Ein nicht so gutes Beispiel sind Börsengeschäfte oder ein Kundenbestellsystem. In diesen Systemen protokollieren Sie die Aktivität wahrscheinlich bereits, da sie einen wichtigen Geschäftswert haben. Das Prinzip der Korrelation mit anderen Aktionen ist jedoch weiterhin wichtig.
Neben benutzerdefinierten Anwendungsprotokollen haben Aktivitäten häufig auch zugehörige Leistungsindikatoren, z. B. die Anzahl der Transaktionen pro Sekunde.
Im Allgemeinen sollten Sie die Protokollierung von Aktivitäten über verschiedene Systeme hinweg koordinieren, dh gleichzeitig mit dem Erhöhen des Leistungsindikators und dem Protokollieren in Ihrem Trace-System in Ihr Anwendungsprotokoll schreiben. Wenn Sie alle gleichzeitig (oder direkt nacheinander im Code) ausführen, ist das Debuggen von Problemen einfacher (als wenn sie alle zu unterschiedlichen Zeiten / Orten im Code auftreten).
(3) Debug Trace - Textdatei oder möglicherweise XML oder Datenbank.
Dies sind Informationen auf ausführlicher Ebene und niedriger (z. B. benutzerdefinierte boolesche Schalter zum Ein- und Ausschalten von Rohdaten-Dumps). Dies liefert den Mut oder die Details dessen, was ein System auf Unteraktivitätsebene tut.
Dies ist die Ebene, die Sie für einzelne Abschnitte Ihrer Anwendung (daher die mehreren Quellen) ein- und ausschalten möchten. Sie möchten nicht, dass dieses Zeug das Windows-Ereignisprotokoll überfüllt. Manchmal wird eine Datenbank verwendet, aber wahrscheinlicher sind fortlaufende Protokolldateien, die nach einer bestimmten Zeit gelöscht werden.
Ein großer Unterschied zwischen diesen Informationen und einer Anwendungsprotokolldatei besteht darin, dass sie unstrukturiert sind. Während ein Anwendungsprotokoll Felder für An, Von, Betrag usw. enthalten kann, können ausführliche Debug-Traces das sein, was ein Programmierer eingibt, z. B. "Überprüfen der Werte X = {Wert}, Y = Falsch" oder zufällige Kommentare / Markierungen wie " Fertig, erneut versuchen ".
Eine wichtige Vorgehensweise besteht darin, sicherzustellen, dass Dinge, die Sie in Anwendungsprotokolldateien oder im Windows-Ereignisprotokoll ablegen, auch mit denselben Details (z. B. Zeitstempel) im Trace-System protokolliert werden. Auf diese Weise können Sie die verschiedenen Protokolle bei der Untersuchung korrelieren.
Wenn Sie planen, einen bestimmten Protokoll-Viewer zu verwenden, weil Sie eine komplexe Korrelation haben, z. B. den Service Trace Viewer, müssen Sie ein geeignetes Format verwenden, z. B. XML. Andernfalls ist eine einfache Textdatei normalerweise gut genug - auf den unteren Ebenen sind die Informationen weitgehend unstrukturiert, sodass Sie möglicherweise Speicherauszüge von Arrays, Stapelspeicherauszügen usw. finden. Vorausgesetzt, Sie können auf höheren Ebenen mit strukturierteren Protokollen korrelieren, sollten die Dinge dies tun in Ordnung sein.
F: Wenn Sie Dateien verwenden, verwenden Sie fortlaufende Protokolle oder nur eine einzelne Datei? Wie stellen Sie die Protokolle für Benutzer zur Verfügung?
A: Für Dateien möchten Sie im Allgemeinen rollierende Protokolldateien unter dem Gesichtspunkt der Verwaltbarkeit (mit System.Diagnostics verwenden Sie einfach VisualBasic.Logging.FileLogTraceListener).
Die Verfügbarkeit hängt wiederum vom System ab. Wenn Sie nur über Dateien sprechen, können Sie für einen Server / Dienst nur bei Bedarf auf fortlaufende Dateien zugreifen. (Windows-Ereignisprotokoll- oder Datenbankanwendungsprotokolle verfügen über eigene Zugriffsmechanismen.)
Wenn Sie keinen einfachen Zugriff auf das Dateisystem haben, ist die Debug-Ablaufverfolgung zu einer Datenbank möglicherweise einfacher. [dh eine Datenbank TraceListener implementieren].
Eine interessante Lösung, die ich für eine Windows-GUI-Anwendung gesehen habe, war, dass sie während der Ausführung sehr detaillierte Ablaufverfolgungsinformationen auf einem "Flugschreiber" protokollierte. Wenn Sie sie dann herunterfahren, wenn sie keine Probleme hatte, wurde die Datei einfach gelöscht.
Wenn es jedoch abstürzte oder auf ein Problem stieß, wurde die Datei nicht gelöscht. Entweder wenn es den Fehler abfängt, oder wenn es das nächste Mal ausgeführt wird, bemerkt es die Datei und kann dann Maßnahmen ergreifen, z. B. komprimieren (z. B. 7zip) und per E-Mail senden oder auf andere Weise verfügbar machen.
Viele Systeme enthalten heutzutage eine automatisierte Meldung von Fehlern an einen zentralen Server (nach Rücksprache mit Benutzern, z. B. aus Datenschutzgründen).
Anzeigen
F: Welche Tools verwenden Sie zum Anzeigen der Protokolle?
A: Wenn Sie aus verschiedenen Gründen mehrere Protokolle haben, verwenden Sie mehrere Viewer.
Notepad / vi / Notepad ++ oder ein anderer Texteditor ist die Basis für Nur-Text-Protokolle.
Wenn Sie komplexe Vorgänge haben, z. B. Aktivitäten mit Übertragungen, würden Sie natürlich ein spezielles Tool wie den Service Trace Viewer verwenden. (Aber wenn Sie es nicht brauchen, ist ein Texteditor einfacher).
Da ich im Allgemeinen allgemeine Informationen im Windows-Ereignisprotokoll protokolliere, bietet es eine schnelle Möglichkeit, sich strukturiert einen Überblick zu verschaffen (achten Sie auf die hübschen Fehler- / Warnsymbole). Sie müssen nur dann mit dem Durchsuchen von Textdateien beginnen, wenn das Protokoll nicht genügend enthält, obwohl das Protokoll Ihnen zumindest einen Ausgangspunkt bietet. (An diesem Punkt ist es hilfreich, sicherzustellen, dass Ihre Protokolle die gesamten Daten koordiniert haben.)
Im Allgemeinen stellt das Windows-Ereignisprotokoll diese wichtigen Ereignisse auch Überwachungstools wie MOM oder OpenView zur Verfügung.
Andere --
Wenn Sie sich bei einer Datenbank anmelden, kann es einfach sein, Informationen zu filtern und zu sortieren (z. B. eine bestimmte Aktivitäts-ID zu vergrößern. (Bei Textdateien können Sie Grep / PowerShell oder ähnliches verwenden, um nach der gewünschten GUID zu filtern.)
MS Excel (oder ein anderes Tabellenkalkulationsprogramm). Dies kann nützlich sein, um strukturierte oder halbstrukturierte Informationen zu analysieren, wenn Sie sie mit den richtigen Trennzeichen importieren können, sodass unterschiedliche Werte in unterschiedlichen Spalten angezeigt werden.
Wenn ich einen Dienst in Debug / Test ausführe, hoste ich ihn normalerweise der Einfachheit halber in einer Konsolenanwendung. Ich finde einen farbigen Konsolenlogger nützlich (z. B. rot für Fehler, gelb für Warnungen usw.). Sie müssen einen benutzerdefinierten Trace-Listener implementieren.
Beachten Sie, dass das Framework keinen farbigen Konsolenlogger oder Datenbanklogger enthält. Daher müssen Sie diese derzeit schreiben, wenn Sie sie benötigen (es ist nicht zu schwierig).
Es ärgert mich wirklich, dass mehrere Frameworks (log4net, EntLib usw.) Zeit damit verschwendet haben, das Rad neu zu erfinden und die grundlegende Protokollierung, Filterung und Protokollierung in Textdateien, dem Windows-Ereignisprotokoll und XML-Dateien jeweils für sich neu zu implementieren unterschiedliche Art und Weise (Protokollanweisungen sind jeweils unterschiedlich); Jeder hat dann seine eigene Version von beispielsweise einem Datenbanklogger implementiert, wenn das meiste davon bereits vorhanden war und nur ein paar weitere Trace-Listener für System.Diagnostics benötigt wurden. Sprechen Sie über eine große Verschwendung von Doppelarbeit.
F: Wenn Sie eine ASP.NET-Lösung erstellen, verwenden Sie auch ASP.NET Health Monitoring? Nehmen Sie die Trace-Ausgabe in die Health Monitor-Ereignisse auf? Was ist mit Trace.axd?
Diese Dinge können nach Bedarf ein- und ausgeschaltet werden. Ich finde Trace.axd sehr nützlich, um zu debuggen, wie ein Server auf bestimmte Dinge reagiert, aber es ist im Allgemeinen in einer stark genutzten Umgebung oder für die Langzeitverfolgung nicht nützlich.
F: Was ist mit benutzerdefinierten Leistungsindikatoren?
Für eine professionelle Anwendung, insbesondere einen Server / Dienst, erwarte ich, dass sie sowohl mit Leistungsindikatoren als auch mit Protokollierung im Windows-Ereignisprotokoll vollständig instrumentiert ist. Dies sind die Standardwerkzeuge in Windows und sollten verwendet werden.
Sie müssen sicherstellen, dass Sie Installationsprogramme für die von Ihnen verwendeten Leistungsindikatoren und Ereignisprotokolle einschließen. Diese sollten zur Installationszeit erstellt werden (bei der Installation als Administrator). Wenn Ihre Anwendung normal ausgeführt wird, sollte sie keine Administratorrechte benötigen (und daher keine fehlenden Protokolle erstellen können).
Dies ist ein guter Grund, die Entwicklung als Nicht-Administrator zu üben (haben Sie ein separates Administratorkonto, wenn Sie Dienste usw. installieren müssen). Wenn Sie in das Ereignisprotokoll schreiben, erstellt .NET beim ersten Schreiben automatisch ein fehlendes Protokoll. Wenn Sie sich als Nicht-Administrator entwickeln, werden Sie dies frühzeitig erkennen und eine böse Überraschung vermeiden, wenn ein Kunde Ihr System installiert und es dann nicht verwenden kann, weil er nicht als Administrator ausgeführt wird.