Geschrieben von: Christoph Wille
Kategorie: ASP.NET
This printed page brought to you by AlphaSierraPapa
Das Event Log unter Windows 2000 (oder NT) ist so ziemlich die wichtigste Informationsquelle für einen Administrator - weil dort sämtliche vorgefallenen Ereignisse vom Erfolg bis zum katastrophalen Mißerfolg vermerkt sind. Und da es so wichtig ist, was liegt näher als diese Informationen über das Web anzeigbar zu machen?
Der Event Viewer (Ereignisanzeige) sollte fast jedem geläufig sein (siehe Bild). In diesem Artikel werde ich zeigen, wie man mit ASP.NET und dem .NET Framework SDK die Liste der Einträge sehr elegant nachbauen kann. Die Zusatzübung für den Leser ist dann, eine Seite für sämtliche Details eines Eintrags zu basteln.
Voraussetzung um den Sourcecode dieses Artikels verwenden zu können ist eine Installation des Microsoft .NET Framework SDK's auf einem Webserver. Weiters setze ich voraus, daß der Leser die Programmiersprache C# zu einem gewissen Grad beherrscht - es finden sich etliche Artikel auf diesem Server, um das notwendige Wissen zu erlernen.
Sicherheitshinweis: die Beispielannahme ist, daß der ASP.NET Worker Prozess unter dem SYSTEM Konto läuft (standardmäßig läuft er unter dem ASPNET Account). Bitte ändern Sie processModel in machine.config entsprechend ab, oder geben nur Administratoren Zugriff auf die Dateien (Impersonation).
Wenn es schnell gehen muß, kann man das Wissen aus ASP-Zeiten durchwegs dazu verwenden, um eine Liste von Ereignissen zu generieren (auch mit Tabelle, obwohl das Beispiel dies nicht tut). Der Name des Programms ist Programm: simple.aspx.
<% @Page Language="C#" %> <% @Import Namespace="System.Diagnostics" %> <% EventLog aLog = new EventLog(); aLog.Log = "System"; aLog.MachineName = "."; // Lokale Maschine string strImage = ""; // Icon für das Event Response.Write("<p>Es sind " + aLog.Entries.Count + " Einträge im System Event Log.</p>"); foreach (EventLogEntry entry in aLog.Entries) { switch (entry.EntryType) { case EventLogEntryType.Warning: strImage = "warning.png"; break; case EventLogEntryType.Error: strImage = "error.png"; break; default: strImage = "info.png"; break; } Response.Write("<img src=\"" + strImage + "\"> | "); Response.Write(entry.TimeGenerated.ToString() + " | "); Response.Write(entry.Source + " | "); Response.Write(entry.EventID.ToString() + "<br>\r\n"); } %>
Die Klassen für das Event Log finden sich im Namespace System.Diagnostics, der am Anfang der Seite eingebunden wird. Das Öffnen des Logs ist an sich sehr einfach: ein neues EventLog Objekt erzeugen, das Log angeben, und dann noch den MachineName ("." ist die lokale Maschine). Und schon kann man aus dem Event Log lesen.
Dies geschieht mit einem foreach Loop. Damit das Listing nicht völlig einfallslos wird, stelle ich noch die korrekten Icons vor jeden Eintrag. Apropos, das Listing der Einträge ist in umgekehrter Reihenfolge, als man es im Event Viewer gewohnt ist: hier sind die ältesten Einträge die ersten.
ASP.NET bringt sehr viele Neuerungen gerade im Bereich der Anzeige von Daten, und das Schöne ist, daß diese Daten nicht immer aus der Datenbank kommen müssen. Dies ist auch für die DataGrid Web Control so, die, wie der Name sagt, eine Tabelle (Grid) aus den Daten erstellt. Die einzige Voraussetzung ist daß die Datenquelle das ICollection Interface unterstützt - und die Entries Collection der EventLog Klasse tut dies.
Der folgende Sourcecode (speccolsonly.aspx) zeigt, wie einfach man das DataGrid einsetzen kann:
<% @Page Language="C#" %> <% @Import Namespace="System.Diagnostics" %> <script language="C#" runat="server"> void Page_Load(Object sender, EventArgs e) { EventLog aLog = new EventLog(); aLog.Log = "System"; aLog.MachineName = "."; LogGrid.DataSource = aLog.Entries; LogGrid.DataBind(); } </script>
Die DataGrid Control (Sourcecode folgt!) beinhaltet nur Formatierungsanweisungen und sonst nichts. Gefüllt wird das Grid mittels des Page_Load Events, welches nur das Event Log öffnet und dann die Entries auf die DataSource Eigenschaft des DataGrid zuweist. Mit dem Aufruf von DataBind werden die Daten dann in die Tabelle gefüllt - und zwar nur die Spalten, die in Columns angegeben wurden. Das sieht dann so aus:
Diese Einschränkung nimmt man im DataGrid Tag selbst vor:
<form runat="server"> <asp:DataGrid id="LogGrid" runat="server" BorderColor="black" BorderWidth="1" GridLines="Both" CellPadding="3" CellSpacing="0" Font-Name="Verdana" Font-Size="8pt" HeaderStyle-BackColor="#aaaadd" AutoGenerateColumns="false"> <Columns> <asp:BoundColumn HeaderText="TOF" DataField="EntryType" /> <asp:BoundColumn HeaderText="Date/Time" DataField="TimeGenerated"/> <asp:BoundColumn HeaderText="Source" DataField="Source"/> <asp:BoundColumn HeaderText="Event ID" DataField="EventID"/> </Columns> </asp:DataGrid> </form>
Der erste wichtige Schritt ist das AutoGenerateColumns Attribut auf false zu setzen. Damit verhindert man, daß automatisch alle Eigenschaften angezeigt werden. Nun kann man angeben, welche Spalten man haben möchte.
Ich verwende hier vier gebundene Spalten (an die Datenquelle gebunden). Der HeaderText wird in der Topzeile des Grids angezeigt, und in DataField steht, welche Eigenschaft ausgelesen werden soll, damit diese Spalte gefüllt wird.
Ich habe dieses Beispiel mit den Spalten (Columns) bewußt einfach gehalten. Es gibt noch viele andere Spaltentypen, und wenn man dann mit den Formatierungen auch noch zum Herumspielen anfängt, dann sind der Gestaltungs-"wut" keine Grenzen mehr gesetzt. Beispiele dafür gibt es im QuickStart Tutorial genug.
Zum Abschluß möchte ich ein weiteres Feature des DataGrid's verwenden, das vielen vom Datenbankprogrammieren ein alter Bekannter ist - das Paging. Der Vorteil des DataGrid's ist der, daß das Paging (fast) ohne Code auskommt, und dann so aussehen könnte:
Diesmal habe ich wieder den gesamten Sourcecode der Seite paging.aspx zum Durchlesen in den Artikel übernommen:
<% @Page Language="C#" %> <% @Import Namespace="System.Diagnostics" %> <script language="C#" runat="server"> void Page_Load(Object sender, EventArgs e) { BindGrid(); } void LogGrid_Change(Object sender, DataGridPageChangedEventArgs e) { // Set CurrentPageIndex to the page the user clicked. LogGrid.CurrentPageIndex = e.NewPageIndex; // Rebind the data. BindGrid(); } void BindGrid() { EventLog aLog = new EventLog(); aLog.Log = "System"; aLog.MachineName = "."; LogGrid.DataSource = aLog.Entries; LogGrid.DataBind(); } </script> <body bgcolor="#ffffff"> <h3>System Event Log</h3> <form runat="server"> <asp:DataGrid id="LogGrid" runat="server" AllowPaging="True" PageSize="10" PagerStyle-Mode="NumericPages" PagerStyle-HorizontalAlign="Right" PagerStyle-NextPageText="Next" PagerStyle-PrevPageText="Prev" OnPageIndexChanged="LogGrid_Change" BorderColor="black" BorderWidth="1" GridLines="Both" CellPadding="3" CellSpacing="0" Font-Name="Verdana" Font-Size="8pt" HeaderStyle-BackColor="#aaaadd" AutoGenerateColumns="false"> <Columns> <asp:BoundColumn HeaderText="TOF" DataField="EntryType" /> <asp:BoundColumn HeaderText="Date/Time" DataField="TimeGenerated"/> <asp:BoundColumn HeaderText="Source" DataField="Source"/> <asp:BoundColumn HeaderText="Event ID" DataField="EventID"/> </Columns> </asp:DataGrid> </form> </body> </html>
Die ersten Änderungen finden sich in der DataGrid Control:
AllowPaging="True" PageSize="10" PagerStyle-Mode="NumericPages" PagerStyle-HorizontalAlign="Right" PagerStyle-NextPageText="Next" PagerStyle-PrevPageText="Prev" OnPageIndexChanged="LogGrid_Change"
Die beiden wichtigsten Attribute sind das erste und das letzte: AllowPaging und OnPageIndexChanged. Ersteres macht das Paging möglich, zweiteres ist die Event-Methode die ausgelöst wird, wenn sich die Seite ändert. Die restlichen Attribute sind kosmetischer Natur.
Da wir in diesem Beispiel mit einer Collection arbeiten, und nicht Datenbankdaten, habe ich es mir beim Paging (fast zu) einfach gemacht: ich binde einfach die Daten noch einmal auf das Grid. Für bessere Performance - speziell für Datenbanken - sollte man dann auch die Daten "häppchenweise" nachladen.
Der eigentliche Zweck des heutigen Artikels war weniger das Auslesen des Event Logs zu erlernen als zu zeigen, wie vielseitig anwendbar das DataGrid auch außerhalb des eigentlichen Hauptanwendungsgebietes der Datenbankprogrammierung ist. Man kann sehr viel der Funktionalität verwenden, auch wenn das Editieren von Event Log Einträgen (read-only) nicht sinnvoll und somit nicht verwendbar ist.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20000811.zip
Das foreach Statement
http:/www.aspheute.com/artikel/20000720.htm
Performance Monitoring a la .NET
http:/www.aspheute.com/artikel/20000809.htm
Services über das Web managen
http:/www.aspheute.com/artikel/20000925.htm
Die aspDEdotnet Diskussionsliste
http://www.dotnetgerman.com/listen/aspDEdotnet.asp
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.