Thursday, August 04, 2005

Event logging the .NET way

Those of you who have used the event logging API are in for a pleasant surprise. In the past, event logging required (comparatively) arduous coding. After creating an executable with specially formatted resources to be used as a message source, you had to register the message source. Then you finally got to write to the event log.

The System.Diagnostics name space contains (among other things) the event logging API. The two classes we'll focus on for reading and writing to the event log in .NET are the EventLog and the EventLogEntry classes.

Write to the event log

Writing to the event log in .NET follows the same basic procedure as using the Win32 API. First, open the event log.

//The period means this machine
EventLog log = new EventLog(“Application”, “.”, “MySource”);

Then write the event:

log.WriteEntry(“Test message”, EventLogEntryType.Information);

Read from the event log

Reading the event log the Win32 way requires you to open the log with the OpenEventLog function and retrieve a handle to the Event Log. Then you have to retrieve the EVENTLOGRECORD structure with the ReadEventLog function.

The EVENTLOGRECORD structure has both static and dynamic fields. In order to access the dynamic fields of the structure such as the message and the source, you have to treat the structure like a byte array. To make things inconsistent, you access the static fields with the dot operator like normal. Although it’s not difficult, it can be error-prone, and if you miscount bytes, you'll get access violations or bad data.

Reading the event log the .NET way is much improved. Instead of dealing with an EVENTLOGRECORD structure, you get to deal with a much safer and easier EventLogEntry class. When you create an EventLog instance pointing at a specific log, the Entries property (which is an instance of the EventLogEntryCollection class) automatically fills with EventLogEntries. You can use the following code to access the Entries collection:

foreach EventLogEntry entry in eventLog.Entries{
    Console.WriteLine(entry.Source);
    Console.WriteLine(entry.Message);
}

Create a custom event log

You can also create a custom event log by calling the static method CreateEventSource of the EventLog class. For example:

//Check to make sure that the source that will
//be associated with the new log doesn’t exist.
//SourceExists is also a static method
if (!EventLog.SourceExists(“MySource”){
    //If MyNewLog does not exist it will be created.
    EventLog.CreateEventSource(“MySource”, “MyNewLog”);
}

As the above code indicates, you can check to see if a source is registered. If the source name already exists, you could overwrite someone else’s source, creating havoc.

Compare the previous code to what you would have to do to create a custom event log with the Win32 API:

  1. Create a message file.

  2. Compile it using the message compiler.(Be sure to include the created resource into the resources of the message synch DLL or Executable.)

  3. Register the message synch (which is about 100 lines of code) in the event system by creating the requisite registry entries.

  4. Take a look at the keys under HKLM\System\CurrentControlSet\Services\EventLog in the registry.

  5. Open and retrieve a handle to an event log.

  6. Now you can write the custom event log.

Conclusion

As you can see, event logging the .NET way is quite easy. The only drawback is that your application has to be running on a version of Windows based on Windows NT. But since Windows XP is the new consumer OS, this issue will soon be moot.

No comments: