Most Windows applications eventually need some sort of logging capabilities; fortunately, the .NET Framework makes working with the Windows Event Log dead simple. While some applications may be better served by using their own special purpose error log mechanisms, the Event Log has the advantages of being where users go to look for errors first and being something that third-party components (such as systems management tools) can monitor.
To get started, you need to understand a few terms:
- Log Entry: Every time an application writes to a log, it creates an entry. An entry can have all sorts of information associated with it, including the event source, an error ID code, and a text message.
- Event Log: The event logs are split into multiple lists of errors; each list is considered an event log. For instance, the Application log that most applications write to is one event log. It is possible to create an event log of your own, if your application will generate enough events to justify splitting them out into a separate log.
- Event Source: Every log entry contains a key piece of information called the event source. The event source tells the reader what application or component generated the log entry. Once an event source is created, any application may write as that source with no restrictions. Every event source is associated with a particular event log; so, if there is a source with the name Test App associated with the Application log, you could not create a source called Test App associated with the System log.
To work with the event log, all of the methods we need are static methods of the EventLog static class in the System.Diagnostics namespace.
Working with event sources
When you create a source, you should see if it exists with the EventLog.SourceExists() method (which accepts the source name as the argument). Remember that there can only be one source on the system with any given name, even if the second source that is trying to be made is in a different log. To create the source, use the EventLog.CreateEventSource method. You can pass this method a log name (if you pass the empty string, the source will be created in the Application log). If the log name does not exist, a new log is created, and the source is associated with it.
Keep in mind that Windows is a bit quirky when it comes to custom source names; for instance, if your source name contains any space characters, the entries will always appear in the Application log even though the custom log (if indicated) will be made and all queries will show that the new source is associated with a different log. So, either remove the space in the source name or convert it to a different character.
You can also delete a source with the EventLog.DeleteEventSource() method, which accepts the source name. There is no way to enumerate the sources on a machine through the .NET Framework's built-in functionality; however, you can do it through the registry using the following code:
private List<string> EnumerateEventSources()
var results = new List<string>();
var eventLogs = EventLog.GetEventLogs();
foreach (var log in eventLogs)
}Note: Editing the registry is risky, so be sure you have a verified backup before saving any changes.
Working with the logs
There is no easy way to see if a log exists, but you can use the EventLog.GetEventLogs()method to get an array of EventLog objects to look within (or to use LINQ to query). There is no way to create a log without also creating an event source, but you can delete a log using the EventLog.Delete() method.
Some of these actions (specifically, creating and deleting sources and logs) require elevated privileges to execute. To do this, you need to add an application manifest to the project (from the Add New Item dialog). After the manifest is added, confirm that your project is using it by looking at the project's property pages. On the Application tab of the properties, ensure that your manifest's name is in the Manifest box. Next, open the manifest file for editing. Look for the requestedExecutionLevel element and set the Level attribute to requireAdministrator. Now, when you run your application under Windows Vista or Windows 7, UAC will prompt for administrator access. In testing, you'll note that it will request that you run Visual Studio as administrator because it is hosting your application.
You're ready to start writing to the Event Log; the EventLog.WriteEntry() method will do this for you. At the minimum, you need to pass a source name and a message, but you can also provide a log message type (Information, Warning, Error, SuccessAudit, and FailureAudit) and an event ID. The event ID must be between 0 and 65535 inclusive. In addition to the static methods for writing log entries, you can instantiate an EventLog object, set its source property, and repeatedly write entries to it.
There is more depth to the Event Log than what I highlight in this overview. For example, you can use localization in your messages, which is something that you may need to check out. Also, it can take some time after creating an event source for it to "take" on the system; it is generally recommended that you create the event source well in advance of actually using it, preferably during an installation.
Also, you can check out a useful little utility I put together for managing the Windows Event Log based on the ideas in this column. The installation package includes the full source code, and it is distributed under the MIT License, so you are more than welcome to do whatever you want with it.Related TechRepublic resource: How do I... Send e-mail alerts when errors are written to the Event Log?
J.JaDisclosure of Justin's industry affiliations: Justin James has a contract with Spiceworks to write product buying guides. He is also under contract to OpenAmplify, which is owned by Hapax, to write a series of blogs, tutorials, and other articles.
--------------------------------------------------------------------------------Get weekly development tips in your inbox Keep your developer skills sharp by signing up for TechRepublic's free Web Developer newsletter, delivered each Tuesday. Automatically subscribe today!
Justin James is the Lead Architect for Conigent.