The event log is a single entity on a single computer. It is a reasonable candidate for a Singleton object, which is guaranteed to exist only once. (For example, System.Console is a Singleton object because there is only one console ”think "command prompt" ”on your PC.) However, instead of making a Singleton object out of the event log, Microsoft permits you to interact with the event log with predominantly shared methods . Additionally, you can create an instance of the EventLog class as you may want to do to send log information to a remote computer or a custom event log.
The event log is a repository for information tracking on a computer. Event information is broken into four general categories: the Application log, the System log, the Security log, and custom logs. The Application log contains user application information. The System log records things happening on the system in general. The Security log keeps track of information regarding the PC's security information. Finally, custom logs are any logs that you create (or an application creates on your behalf ) for any use desired.
A good use of a custom event log is to log Trace and Debug information before you deploy your application. Using a custom log may be preferable to using the Application log to separate the entries made by your application from the general system noise introduced by other applications. There is another reason a custom log might be preferable for testing: writing a lot of entries may quickly exceed the capacity of the Application log, requiring you to clear the entries frequently. If you use the Application log, you may unwittingly delete other Application entries that you need to see in order to resolve some unrelated problem.
Earlier I demonstrated how to use an EventLogTraceListener instance. By default Trace messages using EventLogTraceListener are written to the Application log. However, suppose we elect to use a custom log and want to send Trace and Debug information to that log? As an example, let's create a custom log for the Calculator application. We will start by looking at basic usage of the Event Log, then proceed to creating a custom log and associating it with our EventLogTraceListener instance.
Sending Information to the Event Log
The most challenging part about using the event log is to keep clear the distinctions between the machine name, log name, and log source. The machine name is the computer name . The period ( . ) refers to the local machine, or you can use an actual name like LAP800 . The log name is literally a file with a .evt extension. For example, the Application log is the name of the Application.evt file used to store Application log entries. The tricky part is the source name. The source name must be distinct within a computer across all logs. For example, if we define the Calculator source in the Application log, we can have only one source named Calculator no matter how many logs we have.
To write to an event log you only need to invoke the shared method EventLog.WriteEntry . Pass the name of a unique source and some text, and the entry is written. For example, System.Diagnostics.EventLog. WriteEntry("VB .NET", "Visual Basic is cool!") will write the text "Visual Basic is cool!" to the Application log. Refer to the test application EventLogDemo.sln for some code to experiment with.
There are shared methods for determining whether an event log and source exist, and there are methods for creating and deleting logs and sources. Keep in mind that the source must be unique across all logs. The next subsection gives some examples of how to check for existing logs and sources and delete them if desired.
Defining a Custom Event Log
Suppose we elected to create a new log every time we ran the Calculator application. We could do this by checking for an existing source and deleting it if it existed, then checking for an existing log and deleting it if it existed. When we were sure that we had no preexisting custom log and source, we could then create new ones for the Calculator application to use. Listing 17.9 demonstrates interactions with the EventLog class that would support this specific behavior.
Listing 17.9 Recreating a Custom Log Each Time the Calculator Runs
Private Function GetLog() As EventLog Const Name As String = "Calculator" If (EventLog.SourceExists(Name)) Then Try EventLog.DeleteEventSource(Name) Catch End Try End If If (EventLog.Exists(Name)) Then EventLog.Delete(Name) End If Return New EventLog(Name, ".", Name) End Function
The first step is to define a constant for the log and source names. The log and source names can be identical; we just can't have more than one log at a time with the same source registered. The next step is to ensure that no other log has this source defined. If the chosen source already exists, we want to delete it. (We have to be a bit circumspect here and make sure we don't delete the source for an important system application; such a maneuver might cause problems.) The second If block performs a similar operation, checking and deleting the custom Calculator log. You can check Event Viewer right before the Return statement near the end of Listing 17.9. You will see that there is no Calculator log immediately before the Return statement, and the Calculator log will appear after the Return statement executes. (You may need to refresh the Event Viewer or collapse and expand the list of logs before the new entry appears.)
Sending Debug and Trace Information to a Custom Event Log
When you have created the custom event log, you can use it as you would any other log, including simply writing entries to it. However, we decided to use our custom log as a trace listener. To send Trace and Debug information to the custom log we need to initialize the EventLogTraceListener constructor with the custom log. Simply pass the result of the GetLog() method as an argument to EventLogTraceListener ” New EventLogTraceListener(GetLog()) ”to supplant the Application log with the custom log. Figure 17.12 shows the custom Calculator log with entries written by the Calculator sample program.
Figure 17.12. Log entries written when we invoke Trace.WriteLine and the Calculator log is used to initialize EventLogTraceListener.