Startseite > Archiv > Wachtmeister Windows protokolliert. Auch für Sie!

Wachtmeister Windows protokolliert. Auch für Sie!

 // FOCUS
Wachtmeister Windows protokolliert. Auch für Sie!
Holger Schwichtenberg
» Nicht nur das Windows-Betriebssystem verwendet Ereignisprotokolle, auch für Anwendungen ist die Ablauf- und Fehlerprotokollierung in diesen persistenten Speicher üblich. Die Nutzung der Ereignisprotokolle war früher nicht immer so einfach, wie es sich manch einer gewünscht hätte. Die .NET Framework Class Library enthält jedoch das nötige Handwerkszeug, mit dessen Hilfe Sie mit Ereignisprotokollen arbeiten können.
| Ereignisprotokolle gibt es nur in den Windows-NT-basierten Betriebssystemen, also in NT 4.0, Windows 2000, Windows XP und Windows .NET Server 2003. Die Anzahl der Ereignisprotokolle auf einem System ist beliebig. Drei Standardprotokolle sind immer vorhanden: System, Anwendung und Sicherheit. Auf einem Server-System gibt es je nach installierten Diensten zusätzliche Protokolle wie Directory Service, DNS Server und File Replication Service. Mit einem MMC-Snap-In lässt sich ein Ereignisprotokoll anzeigen (siehe Abbildung 1).

System.Diagnostics
   Die Klassen zur Nutzung der Ereignisprotokolle findet der .NET-Entwickler im Namespace System.Diagnostics. Folgende Aufgaben können mit diesen Klassen erledigt werden:

Lesen von Ereignisprotokolleinträgen,
Überwachen eines Protokolls hinsichtlich neuer Einträge,
Schreiben von neuen Einträgen in das Protokoll,
Anlegen eines neuen, benutzerdefinierten Ereignisprotokolls,
Leeren eines Protokolls,
Löschen eines benutzerdefinierten Protokolls.

   System.Diagnostics enthält neben dem Zugriff auf die Ereignisprotokolle auch Klassen für die Steuerung von Prozessen, den Zugriff auf die Leistungsindikatoren (Performance Counter) von Windows und das Tracing. Für die Arbeit mit Ereignisprotokollen sind die in Tabelle 1 genannten und in Abbildung 2 im Objektmodell gezeigten Klassen wichtig.

Liste aller Ereignisprotokolle
   Die erste Aufgabe soll das Ermitteln der Namen der existierenden Ereignisprotokolle sein. In Listing 1 liefert die statische Methode GetEventLogs aus der Klasse EventLog ein Array of String mit den Namen aller Ereignisprotokolle eines Computers. Als Parameter kann ein Computername übergeben werden, sodass auch Fernzugriffe möglich sind.
   Mit der Methode Exists kann unter Angabe eines Ereignisprotokollnamens geprüft werden, ob ein entsprechendes Protokoll existiert.

Auslesen eines Ereignisprotokolls
   Der Zugriff auf den Inhalt eines Ereignisprotokolls beginnt mit der Instanzierung der Klasse EventLog unter Angabe des Namens des zu verwendenden Protokolls im Konstruktor:

new EventLog(„logname“)

   Die Klasse unterstützt auch den Fernzugriff, indem neben dem Protokollnamen als zweiter Parameter ein Computername angegeben wird:

new EventLog(„logname“,“computername“)

   Das Attribut Entries des so instanzierten EventLog-Objekts verweist auf eine Collection vom Typ EventLogEntryCollection. Diese Collection enthält einzelne Objekte des Typs EventLogEntry, die jeweils einen Protokolleintrag enthalten.
Die Einträge sind nach dem Eintragsdatum geordnet, wobei die ältesten Einträge vorn in der Collection stehen. Es gibt keine eingebaute Möglichkeit, die Einträge zu selektieren. Listing 2 begrenzt die Anzahl der auszugebenden Einträge anwendungsseitig über einen Zähler.

Anlegen eines neuen Ereignisprotokolls
   Mithilfe der Methode CreateEventSource aus der Klasse EventLog kann man ein neues Ereignisprotokoll anlegen. Es wird in die Registry unter HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\Services\Eventlog eingetragen und ist dann im MMC-Snap-In Ereignisanzeige sichtbar. Wenn die MMC-Konsole bereits vor dem Anlegen geöffnet ist, wird das neue Ereignisprotokoll erst nach dem Schließen und dem erneuten Start der MMC-Konsole sichtbar.
   Durch CreateEventSource wird primär eine so genannte Ereignisquelle angelegt. Jeder Ereignisquelle ist genau einem Ereignisprotokoll zugeordnet. Sie ist das Instrument zum Schreiben eines Eintrags, wobei nicht direkt in das Ereignisprotokoll geschrieben wird.
   Wenn beim Aufruf von CreateEventSource das angegebene Ereignisprotokoll nicht existiert, wird es automatisch angelegt. Möchte man das Ereignisprotokoll für eine Ereignisquelle ändern, muss man zunächst mit DeleteEventSource die Ereignisquelle löschen.

Vorsicht, Falle!
   Lediglich die ersten acht Zeichen eines Ereignisprotokollnamens werden zur Unterscheidung verschiedener Ereignisprotokolle herangezogen. Diese Zeichen dürfen also nicht den ersten acht Zeichen eines bereits vorhandenen Protokolls entsprechen.
   Ein Ereignisprotokoll darf außerdem nicht den Namen einer bestehenden Ereignisquelle erhalten.
   Listing 3 legt auf dem Computer Mars ein neues Ereignisprotokoll mit dem Namen DotNetPro an.

Beschreibungstext nicht wählbar
   Nicht beeinflussen kann man den Beschreibungstext für ein neues Ereignisprotokoll, der im MMC-Snap-In Ereignisanzeige angezeigt wird. Dort steht immer Benutzerdefinierte Protokollfehlereinträge. Das ist gerade auch wegen der schlechten Übersetzung ein unbefriedigender Eintrag (Abbildung 3).

Löschen eines Ereignisprotokolls
   Das Löschen eines Ereignisprotokolls ist ein Zweizeiler. Nach dem Instanzieren der Klasse EventLog ruft Listing 4 die statische Methode Delete unter Angabe des Protokollnamens sowie des Computernamens auf. Mit der Methode Clear kann ein Ereignisprotokoll geleert werden, ohne dabei das Protokoll selbst zu entfernen.

EventLogInstaller
   Ebenso kann es vorkommen, dass man – auch als Administrator – ein Ereignisprotokoll nicht in der MMC löschen kann. Kommt das zuvor vorgestellte Verfahren zum Anlegen eines Ereignisprotokolls zum Einsatz, bleibt das Ereignisprotokoll erhalten, wenn die Anwendung durch einfaches Löschen im Dateisystem vom Computer entfernt wird. In diesem Fall gibt es keine Möglichkeit, den Programmcode zum Löschen des Ereignisprotokolls auszuführen.
Das .NET Framework bietet zur Vermeidung solcher Situationen alternativ zum XCOPY-Deployment auch die Verwendung von Installationsklassen an. Eine Installationsklasse beinhaltet Aufgaben, die ausgeführt werden, wenn eine Assembly über das Werkzeug InstallUtil.exe oder über ein Setup-Projekt installiert wird.
Eine Installationsklasse muss folgende Voraussetzungen erfüllen:

Die Klasse muss von System.Configuration.Install.Installer erben.
Die Klasse muss öffentlich sein.
Die Klasse muss mit dem Attribut <System.ComponentModel.RunInstaller(True)> ausgezeichnet werden.
Die auszuführenden Aktionen müssen im parameterlosen Konstruktor definiert werden, indem Installer-Klassen der Collection Installers hinzugefügt werden.

   Für Ereignisprotokolle gibt es die Klasse System.Diagnostics.EventLogInstaller, von der in Listing 5 eine Instanz mit Werten belegt und dann zu der von System.Configuration.Install.Installer geerbten Installers-Collection hinzugefügt wird. Die verschiedenen Ereignisbehandlungsroutinen (BeforeInstall, AfterInstall, BeforeUninstall, AfterUninstall) sind mit Dialogboxen belegt, um den Installationsvorgang verfolgen zu können.
   Die Installation wird folgendermaßen gestartet:

installutil.exe DotNetPro_0103.exe

   Bei erfolgreicher Installation folgen zahlreiche Meldungen, die Listing 6 in Ausschnitten wiedergibt. Die Deinstallation ist möglich über:

installutil.exe /u DotNetPro_0103.exe

   Im Gegensatz zur manuellen Installation überwacht der Installationsprozess die 8-Zeichen-Regel für den Ereignisprotokollnamen und würde den Versuch, ein Ereignisprotokoll DotNetPro2 bei vorhandenem Ereignisprotokoll DotNetPro zu erstellen, so quittieren:

System.ArgumentException: Only the first eight characters of a custom log name are significant, and there is already another log on the system using the first eight characters of the name given. Name given: ‘DotNetPro2’, name of existing log: ‘DotNetPro’.

Setup-Projekt
   Alternativ zur Verwendung von InstallUtil.exe können Sie auch ein Setup-Projekt mit Visual Studio .NET erzeugen, um Ihre Anwendung komfortabel über eine Setup.exe oder ein Microsoft-Installer-Paket (MSI) installieren zu können. Ein Beispiel für ein Setup-Projekt zur obigen Installationsklasse finden Sie auf der Heft-CD (siehe Abbildung 4).

Schreiben in das Ereignisprotokoll
   Eine leichte Übung ist das Erzeugen eines neuen Eintrags in einem Ereignisprotokoll. Nach der Instanzierung eines EventLog-Objekts steht die Methode WriteEntry zur Verfügung. Sie erwartet vier Parameter:

den Namen der Quelle (String),
den Inhalt des Eintrags (String),
den Typ des Eintrags (ein Wert aus der Enumeration System.Diagnostics.EventLogEntryType, siehe Tabelle 2),
eine Ereigniskennung (ein beliebiger Integer-Wert).

   Wird bei WriteEntry eine unbekannte Quelle angegeben, wird diese automatisch in die Registry eingetragen.
   Listing 7 zeigt das Anlegen eines Eintrags in das zuvor erzeugte neue Ereignisprotokoll DotNetPro. Der Code-Block, der die Quelle anlegt, ist optional, da die Quelle automatisch erzeugt wird, wenn sie nicht vorhanden ist.
   Als unvorteilhaft, aber unvermeidbar erweist es sich, dass Microsoft im MMC-Snap-In Ereignisanzeige immer einen Hyperlink zu seiner eigenen Website unter einem Eintrag anzeigt (siehe Abbildung 5), auch wenn das Ereignis von einer Anwendung generiert wird, die gar nicht von Microsoft stammt.

Tracing in ein Ereignisprotokoll
   Das übliche Instrument zur Ablaufverfolgung in .NET-Anwendungen ist die Klasse System.Diagnostics.Trace mit ihren statischen Mitgliedern Write, WriteIf, WriteLine und WriteLineIf. Die Ausgaben der Trace-Klasse können in das Ereignisprotokoll umgeleitet werden, indem ein so genannter Trace-Listener registriert wird. Diese Registrierung erfolgt durch Anhängen einer Instanz der Klasse EventLogTraceListener an die statische Listeners-Collection der Klasse Trace.
   Wenn man bei der Instanzierung des EventLogTraceListener-Objekts nur eine Zeichenkette angibt, dann erfolgt die Protokollierung in das Anwendungsprotokoll unter dem angegebenen Namen als Ereignisquelle. Alternativ kann ein Objekt des Typs EventLog dem Konstruktor übergeben werden. Dabei hat der Entwickler die Möglichkeit, den Namen des Ereignisprotokolls frei zu wählen.

Überwachung eines Ereignisprotokolls
   Selbst wenn eine Anwendung die Windows-Ereignisprotokolle nicht aktiv nutzen möchte, so sind sie dennoch wichtig, um den Zustand des Betriebssystems und anderer Anwendungen zu kontrollieren. In der Klasse EventLog ist das Ereignis EventWritten definiert, das immer dann ausgelöst wird, wenn in das Ereignisprotokoll, welches das EventLog-Objekt repräsentiert, ein neuer Eintrag geschrieben wird. Eine Ereignisbehandlungsroutine für EventWritten erhält über ein Objekt des Typs EntryWrittenEventArgs Informationen über den neuen Eintrag.
Das Beispiel in Listing 9 zeigt die Überwachung des Protokolls DotNetPro. Mit AddHandler wird das Ereignis an NeuerEintrag gebunden. Nach einer kurzen Pause mit Thread.Sleep ruft die Routine zweimal EventLog_Write aus Listing 5 auf. Entsprechend wird die Ereignisbehandlungsroutine NeuerEintrag zweimal aufgerufen.
» Über den Autor
Holger Schwichtenberg ist freiberuflicher Programmierer, Consultant, Dozent und Autor. Er unterrichtet an Hochschulen und spricht regelmäßig auf Konferenzen zu Programmierthemen im Microsoft-Umfeld. Bei Addison-Wesley und Microsoft Press hat er mehrere Programmierbücher veröffentlicht.
www.DotNetFramework.de
Login
Sie sind nicht eingeloggt.

Login & Registrierung
Abo bestellen










Newsletter
Tragen Sie Ihre E-Mailadresse für den kostenlosen Newsletter von dotnetpro ein.


Umfrage
Wieviele Rechner haben Sie kostenlos auf Windows 10 umgestellt?





Ergebnis anzeigen