Tracking the Big Event: Part II

In this second of two parts on using the EventLog classes, KenGetz shows us how to write to the event log, how to handle localized text, andhow to work with events raised by the event log.

ITPro Today

October 30, 2009

8 Min Read
ITPro Today logo in a gray background | ITPro Today

Class Act

Languages: VB

Technologies: .NET Framework | Event Logging

 

Trackingthe Big Event: Part II

Writing to the Event Log Is Easier than Ever

 

By Ken Getz

 

PartI of this article showed how to interact with Windows event log, andintroduced 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 localizedtext, and how to work with events raised by the event log.

 

As partof your applications, you may want to write entries into the event log. You canuse the WriteEntry method (eithercalling the shared WriteEntry orusing the method of an EventLoginstance) to write a new entry to the event log. To write an entry to an eventlog successfully, you ll need to meet the following criteria:

  • Youcan t write an entry to an EventLogobject until you ve set the Sourceproperty of the object. (You can set the Sourceproperty directly, or you can pass the information with the call to WriteEntry.) When your applicationattempts to write an entry, the .NET Framework checks to see if your source hasbeen registered already with the particular event log to which it s trying towrite. If necessary, the framework calls CreateEventSourcefor you. But it can t do that if you haven t indicated the unique string you dlike to use as your application s source name.

  • Themessage you re trying to write can t be longer than 16384 bytes.

  • Youhave to have write permissions for the log you re trying to write into.

 

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

  • Message (String): the text to write to theevent 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 EventLogEntryTypeenumeration.

  • Source (String): the source by which theapplication is registered on the specified computer. If you haven t registeredthis source with the log already, it will be done for you. The name must beunique on the specified computer, or you ll raise an exception.

  • EventID (Integer): an application-specificidentifier for the entry. This can be any value your application cares to passin. The default value for this parameter is 0.

  • Category (Short): an application-specificsubcategory associated with the event.

  • RawData (Byte): an array of bytes holdingthe data you d like to associate with the entry. (What system administratorhasn t seen the infamous The data is the error log entry, which includes abyte array containing the error value for a system error?)

 

Thesample page that writes to the event log, shown in FIGURE 1, uses theoverloaded version of WriteEntrythat 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 pageinto 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 toevent logs. Beware: The Security logis 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) HandlesbtnWriteEntry.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 NewEventLog(ddlEventLogs.SelectedItem.Text)

  el.Source = txtEventSource.Text

  el.MachineName = txtMachine.Text

  If txtMessage.Text <> String.EmptyThen

    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 handlerfor the Write Entry button.

 

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

 


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

 

Whatcould go wrong? Lots of things. You could try to write to the event log beforesetting the Source property of your EventLog object. You might attempt towrite to an invalid machine s registry, or one to which you don t havesufficient rights to write. Perhaps the message you sent was too long (it slimited to 16384 bytes). In any case, check the documentation for the specificoverloaded version of the WriteEntrymethod you re calling. The documentation is very specific about the exactexceptions you might raise when writing to the event log. Pay attention and addCatch blocks for all that make sensein your application.

 

Handling Localized Text

Becauseapplications might run in multiple locales, you may not want your applicationto send text in your local language to the event log. It doesn t do anyone anygood to see text in the event log if it isn t readable because it s in aforeign language. Microsoft has set up a level of indirection on thelocalizable text to allow developers to supply resource files containingmessages and categories in separate files, which are loadable at run time.Setting up text corresponding to CategoryID values requires creating a messagefile that s compiled using the Microsoft Message Compiler. (This tool and documentation about creatingresource files using it are available as part of the Platform SDK for youroperating 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 HKLMCurrentControlSetEventLogApplicationApplicationName,where ApplicationName contains the name of the application you reregistering, you ll find the names of the loadable files that provide thelocalized 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 .NETFramework sends message text directly to the event log. It doesn t take intoaccount any localized messages and placeholders. Therefore, as far as I cantell, the concept of creating localized text applies only to the CategoryID ifyou re using the WriteEntry method.If you supply the CategoryID, the Event Viewer application can look up thecorresponding text in the registered resource file for display within the eventlist.)

 


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

 

Creatingthe message and category files is beyond the scope of this article, but you llfind documentation and information in the Windows Platform SDK, if you want todefine your own categories and messages.

 

There s More

Ifyou re interested in digging deeper, there are a few more issues that haven tbeen covered here. For example, Windows Management Interface (WMI) providesclasses that wrap up event log functionality. WMI also provides a querylanguage all its own, WQL, for retrieving subsets of data. For example, youcould create a WQL query that would retrieve all the events in a particular logcontaining a particular Sourceproperty. 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 Frameworkdoes provide support for WMI classes and queries, but I ve not dug into it yet.

 

Althoughit doesn t make much sense from an ASP.NET application, the EventLog object also supports the EntryWritten event. If you were writinga Windows application, or a class library, you might want to watch for entriesadded 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 theWithEvents keyword, like this:

 

Private WithEvents el as EventLog

 

(Don tforget to add the Imports System.Diagnostics statement to your module, as well.) Then, withinsome procedure, instantiate the variable, hooking it up to receive eventnotifications 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

 

Thisprocedure causes the variable, el, to refer to the Application event log (you could choose any event log). Inaddition, the code sets the EnableRaisingEventsproperty of the EventLog object. Ifyou don t set this property, you ll never receive any event notificationsbecause the EventLog object includesa tricky optimization. The developers of the class realized you d seldom wantto sit and wait for real-time notifications (they can be expensive on a busysystem). To avoid the overhead of blasting notifications for each entry thatcomes into the event log, by default the EventLogclass doesn t raise its events. Once you set the EnableRaisingEvents property to True, however, the EventLogobject raises the EntryWritten eventeach time a new entry appears in the log.

 

To reactto the EntryWritten event, you canadd 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

 

Thissimple procedure merely writes the Messageproperty of the Entry object (passedin as a property of the EntryWrittenEventArgsobject parameter) to the Consolewindow, but you can use any property of the Entry object to take whatever action you need.

 

Again, Idon t see how this will be of use to ASP.NET developers who aren t also workingin other types of applications, but it s good to know the capability isavailable should you ever need it.

 

The files referenced in this article are available for download.

 

Ken Getz isa senior consultant with MCW Technologies and splits his time betweenprogramming, writing, and training. He specializes in tools and applicationswritten in Visual Studio .NET and Visual Basic. Ken is co-author of severalbooks, including Access 2002 Developer s Handbook with Paul Litwin and MikeGunderloy, Visual Basic Language Developer s Handbook with Mike Gilbert, and VBA Developer s Handbook with Mike Gilbert. Ken co-wrote the training materials forAppDev s ASP.NET, Access 97 and 2000, Visual Basic 5.0, and Visual Basic 6.0classes. He frequently speaks at technical conferences and is a contributingeditor for Microsoft Office Solutions magazine.

 

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

 

 

 

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like