Skip navigation

Tracking the Big Event: Part II

Class Act

Languages: VB

Technologies: .NET Framework | Event Logging

 

Tracking the Big Event: Part II

Writing to the Event Log Is Easier than Ever

 

By Ken Getz

 

Part I of this article showed how to interact with Windows event log, and introduced the concepts of the event source and how to work with event sources. In this part, you ll see how to write to the event log, how to handle localized text, and how to work with events raised by the event log.

 

As part of your applications, you may want to write entries into the event log. You can use the WriteEntry method (either calling the shared WriteEntry or using the method of an EventLog instance) to write a new entry to the event log. To write an entry to an event log successfully, you ll need to meet the following criteria:

  • You can t write an entry to an EventLog object until you ve set the Source property of the object. (You can set the Source property directly, or you can pass the information with the call to WriteEntry.) When your application attempts to write an entry, the .NET Framework checks to see if your source has been registered already with the particular event log to which it s trying to write. If necessary, the framework calls CreateEventSource for you. But it can t do that if you haven t indicated the unique string you d like to use as your application s source name.
  • The message you re trying to write can t be longer than 16384 bytes.
  • You have to have write permissions for the log you re trying to write into.

 

The WriteEntry method provides 10 overloaded versions, which allow you to pass in different combinations of parameters. You can pass a number of parameters, including:

  • Message (String): the text to write to the event entry.
  • Type (EventLogEntryType): the type of event to log. It can be one of Error, FailureAudit, Information, SuccessAudit, or Warning. All are members of the EventLogEntryType enumeration.
  • Source (String): the source by which the application is registered on the specified computer. If you haven t registered this source with the log already, it will be done for you. The name must be unique on the specified computer, or you ll raise an exception.
  • EventID (Integer): an application-specific identifier for the entry. This can be any value your application cares to pass in. The default value for this parameter is 0.
  • Category (Short): an application-specific subcategory associated with the event.
  • RawData (Byte): an array of bytes holding the data you d like to associate with the entry. (What system administrator hasn t seen the infamous The data is the error log entry, which includes a byte array containing the error value for a system error?)

 

The sample page that writes to the event log, shown in FIGURE 1, uses the overloaded version of WriteEntry that passes most of the available parameters. The code for the Click event handler for the Write Entry button uses brute force to convert the control values on the page into the appropriate data types. The code also calls the WriteEntry method for you (see FIGURE 2).

 


FIGURE 1: Use this page, WriteEntry.aspx, to test writing to event logs. Beware: The Security log is read-only, so you won t be able to write to it.

 

Private Sub btnWriteEntry_Click( _

 ByVal sender As System.Object, _

 ByVal e As System.EventArgs) Handles btnWriteEntry.Click

 

  Dim abytes() As Byte = _

  {CByte(txtByte0.Text), CByte(txtByte1.Text), _

   CByte(txtByte2.Text), CByte(txtByte3.Text), _

   CByte(txtByte4.Text), CByte(txtByte5.Text), _

   CByte(txtByte6.Text), CByte(txtByte7.Text)}

 

  Dim el As New EventLog(ddlEventLogs.SelectedItem.Text)

  el.Source = txtEventSource.Text

  el.MachineName = txtMachine.Text

  If txtMessage.Text <> String.Empty Then

    el.WriteEntry( _

     txtMessage.Text, _

     CType(ddlEntryType.SelectedItem.Value, _

     EventLogEntryType), _

     CInt(txtEventID.Text), _

     CShort(txtCategory.Text), _

     abytes)

  End If

End Sub

FIGURE 2: The code for the Click event handler for the Write Entry button.

 

FIGURE 3 shows the results of writing this entry to the event log. As you can see, all the data passed from the sample page ends up in the appropriate locations.

 


FIGURE 3: After writing to the event log, use the Event Properties screen to verify your new entry.

 

What could go wrong? Lots of things. You could try to write to the event log before setting the Source property of your EventLog object. You might attempt to write to an invalid machine s registry, or one to which you don t have sufficient rights to write. Perhaps the message you sent was too long (it s limited to 16384 bytes). In any case, check the documentation for the specific overloaded version of the WriteEntry method you re calling. The documentation is very specific about the exact exceptions you might raise when writing to the event log. Pay attention and add Catch blocks for all that make sense in your application.

 

Handling Localized Text

Because applications might run in multiple locales, you may not want your application to send text in your local language to the event log. It doesn t do anyone any good to see text in the event log if it isn t readable because it s in a foreign language. Microsoft has set up a level of indirection on the localizable text to allow developers to supply resource files containing messages and categories in separate files, which are loadable at run time. Setting up text corresponding to CategoryID values requires creating a message file that s compiled using the Microsoft Message Compiler. (This tool and documentation about creating resource files using it are available as part of the Platform SDK for your operating system.) Once you ve created your category and message text files, you must make their locations known in the system registry. If you look under HKLM\CurrentControlSet\EventLog\Application\ApplicationName, where ApplicationName contains the name of the application you re registering, you ll find the names of the loadable files that provide the localized messages. FIGURE 4 shows a section of the registry, on my machine, with these files listed. (It s interesting to note that the WriteEntry method provided by the .NET Framework sends message text directly to the event log. It doesn t take into account any localized messages and placeholders. Therefore, as far as I can tell, the concept of creating localized text applies only to the CategoryID if you re using the WriteEntry method. If you supply the CategoryID, the Event Viewer application can look up the corresponding text in the registered resource file for display within the event list.)

 


FIGURE 4: COM+ has registered a message file, a category file, and a parameter message file in the registry, so the Event Viewer application can look up language-specific replacements.

 

Creating the message and category files is beyond the scope of this article, but you ll find documentation and information in the Windows Platform SDK, if you want to define your own categories and messages.

 

There s More

If you re interested in digging deeper, there are a few more issues that haven t been covered here. For example, Windows Management Interface (WMI) provides classes that wrap up event log functionality. WMI also provides a query language all its own, WQL, for retrieving subsets of data. For example, you could create a WQL query that would retrieve all the events in a particular log containing a particular Source property. The EventLog class in .NET doesn t make this possible, though. You must iterate through all the items in the Entries collection and weed them out yourself. The .NET Framework does provide support for WMI classes and queries, but I ve not dug into it yet.

 

Although it doesn t make much sense from an ASP.NET application, the EventLog object also supports the EntryWritten event. If you were writing a Windows application, or a class library, you might want to watch for entries added to an event log and react to the new entries in real time. For example, in a Windows application, you could create a class-level variable that uses the WithEvents keyword, like this:

 

Private WithEvents el as EventLog

 

(Don t forget to add the Imports System.Diagnostics statement to your module, as well.) Then, within some procedure, instantiate the variable, hooking it up to receive event notifications from the event log:

 

Private Sub Button1_Click( _

 ByVal sender As System.Object, _

 ByVal e As System.EventArgs) _

 Handles Button1.Click

  el = New EventLog("Application")

  el.EnableRaisingEvents = True

End Sub

 

This procedure causes the variable, el, to refer to the Application event log (you could choose any event log). In addition, the code sets the EnableRaisingEvents property of the EventLog object. If you don t set this property, you ll never receive any event notifications because the EventLog object includes a tricky optimization. The developers of the class realized you d seldom want to sit and wait for real-time notifications (they can be expensive on a busy system). To avoid the overhead of blasting notifications for each entry that comes into the event log, by default the EventLog class doesn t raise its events. Once you set the EnableRaisingEvents property to True, however, the EventLog object raises the EntryWritten event each time a new entry appears in the log.

 

To react to the EntryWritten event, you can add an event procedure, as shown here:

 

Private Sub el_EntryWritten( _

 ByVal sender As Object, _

 ByVal e As EntryWrittenEventArgs) _

 Handles el.EntryWritten

  Console.WriteLine(e.Entry.Message.ToString)

End Sub

 

This simple procedure merely writes the Message property of the Entry object (passed in as a property of the EntryWrittenEventArgs object parameter) to the Console window, but you can use any property of the Entry object to take whatever action you need.

 

Again, I don t see how this will be of use to ASP.NET developers who aren t also working in other types of applications, but it s good to know the capability is available should you ever need it.

 

The files referenced in this article are available for download.

 

Ken Getz is a senior consultant with MCW Technologies and splits his time between programming, writing, and training. He specializes in tools and applications written in Visual Studio .NET and Visual Basic. Ken is co-author of several books, including Access 2002 Developer s Handbook with Paul Litwin and Mike Gunderloy, Visual Basic Language Developer s Handbook with Mike Gilbert, and VBA Developer s Handbook with Mike Gilbert. Ken co-wrote the training materials for AppDev s ASP.NET, Access 97 and 2000, Visual Basic 5.0, and Visual Basic 6.0 classes. He frequently speaks at technical conferences and is a contributing editor for Microsoft Office Solutions magazine.

 

Tell us what you think! Please send any comments about this article to [email protected]. Please include the article title and author.

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish