To read the article online, visit http://www.4GuysFromRolla.com/webtech/chapters/ASPNET2/ch02.9.shtml

ASP.NET: Tips, Tutorials, and Code
Chapter 2: Common ASP.NET Code Techniques


9. Accessing the Windows Event Log

Hopefully, by now you realize that there are a plethora of tasks you can do with ASP.NET which, with classic ASP, were impossible or extremely difficult without the use of a COM component. One such task that was not possible with just classic ASP was the ability to access the Windows event log. The .NET Framework, however, contains a number of classes that allow developers to both read and write to the event log!

This means that you can create an ASP.NET page through which a user could view event log history. Such functionality, coupled with the ProcessInfo ASP.NET page discussed in "Using ProcessInfo: Retrieving Information about a Process," could be used to create a very powerful remote administration tool for site information and maintenance purposes. Additionally, because an ASP.NET page can write entries to the event log, you could have various ASP.NET errors recorded to the Windows event log.

This section is broken down into two parts. In the first part, "Reading from the Event Log," we'll look at an ASP.NET page that displays the current entries from a selected log. In the second part, "Writing to the Event Log," we'll examine how to record events to the event log.

Reading from the Event Log

The .NET Framework contains a number of classes to read and write to the event log, all of which reside in the System.Diagnostics namespace. The main class that provides access to the event log is aptly named EventLog. Keep in mind that the Windows event log can contain many logs itself. Windows 2000 comes with three default logs: the Application log, the Security log, and the System log. The EventLog class can read and write to any of these various logs. In fact, the EventLog class can even be used to create new logs in the Windows event log.


Note

The EventLog class can be used to read and write to remote computers' Windows event logs as well as for the Web server's Windows event log. For more information on accessing remote event logs, refer to the documentation for the EventLog class.


Listing 2.9.1 shows a very simple ASP.NET page that displays the event log entries in the System event log that have been registered as errors. The output of Listing 2.9.1, when viewed through a browser, can be seen in Figure 2.28.

Listing 2.9.1 The EventLog Class Provides Access to the Windows Event Log

 1: <%@ Import Namespace="System.Diagnostics" %>
 2: <script language="VB" runat="server">
 3:  Sub Page_Load(sender as Object, e as EventArgs)
 4:   Dim objEventLog as EventLog = New EventLog("System")
 5:
 6:   Dim objEntry as EventLogEntry
 7:   For Each objEntry in objEventLog.Entries
 8:    If objEntry.EntryType = EventLogEntryType.Error then
 9:     Response.Write(objEntry.TimeGenerated & " - " & _
10:            objEntry.Source & " - " & _
11:            objEntry.Message & "<br>")
12:    End If
13:   Next
14:  End Sub
15: </script>

Figure 2.28
Displays the error entries in the System log.

Listing 2.9.1 begins with an Import directive to include the namespace of the EventLog class, System.Diagnostics. In the Page_Load event handler, an instance of the EventLog class, objEventLog, is created (line 4). There are many forms of the EventLog constructor; on line 4, we used the one that expects a single String parameter specifying the log filename to open.

Each log in the Windows event log is composed of a number of entries. The .NET Framework provides an abstraction of each event log entry as a class, EventLogEntry. The EventLog class contains an Entries property that exposes a collection of EventLogEntry instances representing all the entries for a specific event log. On lines 7 through 13, we iterate through this collection using a For Each ... Next loop (line 7).

The EventLogEntry class contains a number of properties that represent an entry in the event log. One of these properties is EntryType, which indicates the type of event log entry. The possible values for this property are defined by the EventLogEntryType enumeration, and include values such as Error, Information, Warning, and others. One line 8, we check to determine if the current EventLogEntry instance in our For Each ... Next loop is an error entry. If it is, we display additional information about the entry (lines 9 through 11); otherwise, we skip on to the next entry.

Although viewing all the error entries for a particular log file might have plausible uses, we could easily create a much more graphically pleasing and easier-to-use interface without much effort. Listing 2.9.2 contains the code for an ASP.NET page that lists all the entries for a user-chosen log file. Furthermore, these event log entries are displayed through the creation of a dynamic HTML table using the various ASP.NET table controls. Figure 2.29 contains a screenshot of Listing 2.9.2 when viewed through a browser.

Listing 2.9.2 The Complete Contents of a User-Chosen Event Log Are Displayed with Pretty Formatting

 1: <%@ Import Namespace="System.Diagnostics" %>
 2: <%@ Import Namespace="System.Drawing" %>
 3: <script language="VB" runat="server">
 4:  Sub Page_Load(sender as Object, e as EventArgs)
 5:   If Not Page.IsPostBack Then
 6:    DisplayEventLog("System")
 7:   End If
 8:  End Sub
 9:
 10:  Sub btnSubmit_OnClick(sender as Object, e as EventArgs)
 11:   DisplayEventLog(lstLog.SelectedItem.Value)
 12:  End Sub
 13:
 14:  Sub btnClear_OnClick(sender as Object, e as EventArgs)
 15:   'Clear all of the event log entries
 16:   Dim objEventLog as New EventLog(lstLog.SelectedItem.Value)
 17:   objEventLog.Clear()
 18:  End Sub
 19:
 20:  Sub DisplayEventLog(strLogName as String)
 21:   Dim objRow as New TableRow
 22:   Dim objCell as New TableCell
 23:
 24:   objCell.BackColor = Color.Bisque
 25:   objCell.HorizontalAlign = HorizontalAlign.Center
 26:   objCell.Text = "Type"
 27:   objRow.Cells.Add(objCell)
 28:
 29:   objCell = New TableCell
 30:   objCell.BackColor = Color.Bisque
 31:   objCell.HorizontalAlign = HorizontalAlign.Center
 32:   objCell.Text = "Date"
 33:   objRow.Cells.Add(objCell)
 34:
 35:   objCell = New TableCell
 36:   objCell.BackColor = Color.Bisque
 37:   objCell.HorizontalAlign = HorizontalAlign.Center
 38:   objCell.Text = "Time"
 39:   objRow.Cells.Add(objCell)
 40:
 41:   objCell = New TableCell
 42:   objCell.BackColor = Color.Bisque
 43:   objCell.HorizontalAlign = HorizontalAlign.Center
 44:   objCell.Text = "Source"
 45:   objRow.Cells.Add(objCell)
 46:
 47:   objCell = New TableCell
 48:   objCell.BackColor = Color.Bisque
 49:   objCell.HorizontalAlign = HorizontalAlign.Center
 50:   objCell.Text = "User"
 51:   objRow.Cells.Add(objCell)
 52:
 53:   objCell = New TableCell
 54:   objCell.BackColor = Color.Bisque
 55:   objCell.HorizontalAlign = HorizontalAlign.Center
 56:   objCell.Text = "Computer"
 57:   objRow.Cells.Add(objCell)
 58:
 59:   tblLog.Rows.Add(objRow)
 60:
 61:
 62:   Dim objEventLog as EventLog = New EventLog(strLogName)
 63:   Dim objEntry as EventLogEntry
 64:
 65:   For Each objEntry in objEventLog.Entries
 66:    objRow = New TableRow
 67:    objCell = New TableCell
 68:
 69:    'Determine the type of error
 70:    If objEntry.EntryType = EventLogEntryType.Error Then
 71:     objCell.BackColor = Color.Red
 72:     objCell.ForeColor = Color.White
 73:     objCell.Text = "Error"
 74:    ElseIf objEntry.EntryType = EventLogEntryType.Information Then
 75:     objCell.Text = "Information"
 76:    ElseIf objEntry.EntryType = EventLogEntryType.Warning Then
 77:     objCell.BackColor = Color.Yellow
 78:     objCell.Text = "Warning"
 79:    ElseIf objEntry.EntryType = EventLogEntryType.SuccessAudit Then
 80:     objCell.Text = "Success Audit"
 81:    ElseIf objEntry.EntryType = EventLogEntryType.FailureAudit Then
 82:     objCell.ForeColor = Color.Red
 83:     objCell.Text = "Failure Audit"
 84:    End If
 85:    objCell.HorizontalAlign = HorizontalAlign.Center
 86:    objRow.Cells.Add(objCell)
 87:
 88:    objCell = New TableCell
 89:    objCell.Text = objEntry.TimeGenerated.ToShortDateString()
 90:    objRow.Cells.Add(objCell)
 91:
 92:    objCell = New TableCell
 93:    objCell.Text = objEntry.TimeGenerated.ToLongTimeString()
 94:    objRow.Cells.Add(objCell)
 95:
 96:    objCell = New TableCell
 97:    objCell.Text = objEntry.Source
 98:    objRow.Cells.Add(objCell)
 99:
100:    objCell = New TableCell
101:    If objEntry.UserName <> Nothing then
102:     objCell.Text = objEntry.UserName
103:    Else
104:     objCell.Text = "N/A"
105:    End If
106:    objRow.Cells.Add(objCell)
107:
108:    objCell = New TableCell
109:    objCell.Text = objEntry.MachineName
110:    objRow.Cells.Add(objCell)
111:
112:
113:    tblLog.Rows.Add(objRow)
114:   Next
115:  End Sub
116: </script>
117:
118: <html>
119: <body>
120:  <form runat="server">
121:   <h1>Event Log Viewer</h1>
122:   <asp:listbox runat="server" id="lstLog" Rows="1">
123:    <asp:listitem>Application</asp:listitem>
124:    <asp:listitem>Security</asp:listitem>
125:    <asp:listitem Selected="True">System</asp:listitem>
126:   </asp:listbox>
127:   <asp:button runat="server" id="btnSubmit" Text="Display Event Log"
128:         OnClick="btnSubmit_OnClick" />
129:   <hr>
130:   <asp:table runat="server" id="tblLog" CellPadding="5"
131:        CellSpacing="0" GridLines="Both" Font-Size="10pt"
132:        Font-Name="Verdana" />
133:   <hr>
134:   <asp:button runat="server" id="btnClear" Text="Clear Event Log"
135:         OnClick="btnClear_OnClick" />
136:  </form>
137: </body>
138: </html>

Figure 2.29
Listing 2.9.2 displays an event log's entries through an ASP.NET page.

Listing 2.9.2 begins by Importing two namespaces: System.Diagnositics, for the EventLog and EventLogEntry classes (line 1); and System.Drawing, for the Color structure that is used to set the foreground and background colors of the table cells (line 2). When the page is loaded for the first time, the Page_Load event handler will fire and line 6 will be reached, in which case the DisplayEventLog subroutine will be called to display the entries in the System log.

The DisplayEventLog subroutine, spanning from line 20 through line 115, displays all the entries for the event log specified by strLogName in a nice format. This format is in the form of an HTML table and created via the ASP.NET table controls (the Table, TableRow, and TableCell Web controls). (For more information on these controls, refer to the .NET Framework Documentation.)

The HTML section for the page, found in lines 118 through 138, starts by defining a postback form (line 120). Next, a list box control is created on line 122 and hard-coded with the three default Windows 2000 event logs: Application, Security, and System (lines 123 through 125). Next, a button, btnSubmit, is created on lines 127 and 128. This button, when clicked, will postback the form and cause the btnSubmit_OnClick event handler to fire. Next, on lines 130, 131, and 132, a table control is created. This is the table control that is dynamically built-up in the DisplayEventLog subroutine. Finally, on lines 134 and 135, another button control is created. When clicked, this button, btnClear, will cause all the event log entries for the selected event log to be cleared.

The btnSubmit_OnClick event handler can be found from lines 10 through 12. It is very simple, containing only one line of code. All it needs to do is display the event log selected by the user. This is accomplished by calling the DisplayEventLog subroutine and passing the Value of the selected list box item (line 11).

The btnClear_OnClick event handler is called when the btnClear button is clicked (see lines 134 and 135). This event handler is responsible for clearing all the event log entries, which is accomplished with the Clear method of the EventLog class (line 17).


Note

Notice that in Listing 2.9.2 we invest nearly 100 lines of code to display the Event Log in an HTML table. We could have used data binding with the DataList control to display this information in far fewer lines of code. However, I wanted to examine code to dynamically build an HTML table. For information on data binding be sure to check out Chapter 7.


Writing to the Event Log

The EventLog class also provides the ability for developers to have information written to the event log. There are a number of real-world situations in which it might be advantageous for an ASP.NET page to be able to make an entry to the Windows event log. In an article on ASPFree.com (http://aspfree.com/asp+/eventlog2.aspx), Steve Schofield demonstrates how to create a global error-handling page so that no matter when or where an ASP.NET error occurs, it is logged to a custom created error log.

Listing 2.9.3 provides similar functionality to Steve Schofield's event log article. Rather than recording any error in any ASP.NET Web page, however, Listing 2.9.3 provides a simple function that can be included in certain ASP.NET pages and called when an error occurs. Furthermore, rather than writing errors to a custom event log, Listing 2.9.3 records errors to the System event log.

Listing 2.9.3 With the .NET Framework, a Developer Can Add Entries to an Event Log via an ASP.NET Page

 1: <%@ Import Namespace="System.Data" %>
 2: <%@ Import Namespace="System.Data.SqlClient" %>
 3: <%@ Import Namespace="System.Diagnostics" %>
 4: <script language="c#" runat="server">
 5:  void Page_Load(Object sender, EventArgs e)
 6:  {
 7:   // Perform some type of illegal operation
 8:   try {
 9:    SqlConnection objConn;
10:    objConn = new SqlConnection("server=localhost;uid=foo;
 pwd=bar;database=pubs");
11:    objConn.Open();
12:    // ...
13:   }
14:   catch (Exception eError)
15:   {
16:    RecordError(eError, EventLogEntryType.Error);
17:   }
18:  }
19:
20:
21:  void RecordError(Exception eError, EventLogEntryType enumType)
22:  {
23:   const String strSource = "ASP.NET",
24:      strLogName = "System";
25:
26:   // Add the strMessage entry to the ASPX event log
27:   EventLog objLog = new EventLog(strLogName);
28:   objLog.Source = strSource;
29:   objLog.WriteEntry(eError.Message, enumType);
30:  }
31: </script>

Listing 2.9.3 demonstrates how an entry can be written to the event log when an error occurs. Although the code in the try block from lines 9 through 11 might seem valid, the connection string specified on line 10 is not. This will cause an error to be thrown on line 11, when attempting to Open the connection. At this point, the catch block will catch the exception and make a call to the RecordError function, which will add an entry to the System event log indicating the error (line 16).

The RecordError function, stretching from line 21 through line 30, adds an entry to the System event log. First, on lines 23 and 24, two constants are defined: strSource, specifying the source of the error, and strLogName, specifying the event log that is to record the error. Next, on line 27, an EventLog instance representing the System event log is created. On line 28, the Source property is set to the constant strSource. Finally, on line 29, an entry is added to the event log. This entry's Message is identical to the Message property of the thrown Exception. The entry type is specified by the developer, passed in as the second parameter to the RecordError function. In Listing 2.9.3, an Error entry type is specified (see line 16).


Note

The Source of the entry added to the event log is used to specify the application or service that caused the error.


Figure 2.30 displays the detailed information for the entry added to the System event log for the error caused by Listing 2.9.2. Note that the event log entry has its source set to "ASP.NET" and indicates that there was an error in accessing the specified database. The RecordError function could be improved to add more detailed error messages, such as the ASP.NET page that threw the error and other relevant information.

Figure 2.30
A new error entry has been added to the System event log.

  • Read Part 10


  • Article Information
    Article Title: Common ASP.NET Code Techniques
    Article Author: Scott Mitchell
    Published Date: Friday, September 28, 2001
    Article URL: http://www.4GuysFromRolla.com/webtech/chapters/ASPNET2/ch02.9.shtml


    Copyright 2014 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers