Published on ONDotNet.com (http://www.ondotnet.com/)
 See this if you're having trouble printing code examples

Instrumenting Your .NET Applicaiton

by Mike Gunderloy

As they refine the .NET story, Microsoft seems to be getting more and more serious about pushing into the "enterprise" space. One of the latest pieces of evidence of this push is the release of the Enterprise Instrumentation Framework (EIF), a set of classes and utilities that work with the .NET languages to provide white-box monitoring for distributed applications. Key features of the EIF include:

In this article, I'll introduce the EIF and give you a broad overview of its workings. By the end of the article, you should be able to judge whether this is a promising model for instrumenting your own enterprise applications.

Setting Up the EIF

Related Reading

Mastering Visual Studio .NET
By Ian Griffiths, Jon Flanders, Chris Sells

If you've never heard of the EIF, you're not alone. Apart from a mention in the "what's new" bullet points of some Visual Studio .NET 2003 presentations, Microsoft has been strangely silent about this new software layer. They've also chosen a very strange method of distributing the EIF: it's available for download, but only to MSDN Universal subscribers. (I assume that it will show up in a future CD or DVD shipment as well.) If you subscribe at that level, you can log on to the MSDN Subscriber Downloads site, where you'll find the EIF listed under the "Tools, SDKs, and DDKs" section.

Along with downloading the EIF bits, you'll want to make sure that you have all of your prerequisites in order before attempting the installation. For an operating system, you'll want Windows XP Pro with SP1, Windows 2000 with SP3, or Windows 2003. (EIF will work on earlier versions of Windows XP and Windows 2000, but there are bugs you need to work around if you're not up to the suggested service-pack levels.) On your development workstation, you need either Visual Studio .NET or Visual Studio .NET 2003. EIF works with either version, though if you're using the original release you must upgrade your .NET Framework install with .NET Framework 1.0 Service Pack 2 or later. Application servers that will run your EIF applications don't need Visual Studio .NET, but they do need the version of the .NET Framework that you used for development. Finally, if you want to work with the WMI interfaces, you should install the WMI SDK; you can get that from the Platform SDK Update Site or from the Platform SDK CD in your MSDN shipment.

With the right prerequisites, installation is a simple matter of running the setup file, but you need to be aware of two things. First, if you've got both versions of the .NET Framework on your machine, there's an issue involving a conflict between the PerformanceCounter classes of the two that can cause setup to fail. The issue is documented (sort of) in Knowledge Base article 813350, and there's a hot fix available. I found the easiest way to deal with this, though, was to reboot my machine and then run the EIF installation before running any other .NET software. Also, for some reason the Windows Trace Session Manager wasn't logging any events after the installation. Stopping and restarting it fixed that problem for me.

The EIF Architecture

Figure 1 provides a high-level overview of the EIF architecture.

EIF architecture
Figure 1. EIF architecture

The overall idea of EIF is to define event sources, which post events from any tier of an application, and event sinks, which can receive events. EIF's own instrumentation API works as a routing layer between sources and sinks, and is controlled by XML configuration files. Those files themselves can be modified by scripting code, creating a convenient way for testers or administrators to manage the details of event logging. If your application begins to fail, for example, you can start capturing detailed information (to a Windows event log, a trace log, or a WMI listener) simply by running a configuration script and without recompiling or stopping any tier of your application. Of course, you have to build in the event sources when you create the application.

Event Sources

In EIF, an event source is an instance of a particular class. When you hook up EIF to your application (by setting a reference to the Microsoft.EnterpriseInstrumentation namespace), it automatically adds a default event source with the reserved name Application. To raise an event, you call the static Raise method of one of the classes contained in the Microsoft.EnterpriseInformation.Schema namespace. If you don't specify a source, the default application source is assumed. The Microsoft.EnterpriseInformation.Schema namespace defines a number of event classes, which you can use to indicate different types of events. For example:

TraceMessageEvent.Raise("Tracing message");
AuditMessageEvent.Raise("Recording an audit record");
AdminMessageEvent.Raise("An administrative event");

Sometimes you may wish to implement event sources at a finer level within your application. For example, you might want to distinguish events raised by your configuration component from events raised by your database component. You can do this by defining your own event sources, which are known as SoftwareElement event sources. In code, this is also very simple:

class ConfigurationComponent
  public static EventSource es = 
                               new EventSource("Configuration");

  // code somewhere in the component
  public void ConfigurationMethod()
    // raise an EIF event
                      "Tracing in the configuration component");

class DatabaseComponent
  public static EventSource es = new EventSource("Database");

  // code somewhere in the component
  public void DatabaseMethod()
    // raise an EIF event
                            "Tracing in the database component");

Event Sinks

The EIF supplies three standard event sinks. You don't have to write any code to make use of these sinks:

You can also define custom event sinks. To do so, you derive a class from the abstract base class EventSink, writing code to send events wherever you like. Custom event sinks must be compiled with a strong name and installed into the Global Assembly Cache (GAC).

Hooking Up the Plumbing

When you're using the EIF, your code won't contain any explicit connections between event sources and event sinks. Instead, a set of configuration files controls these connections at runtime. This has the great advantage that you can customize the configuration to save more or fewer events depending on circumstances. In routine operation, you might not hook up any event sources to event sinks at all; in this case, all of the events are discarded with minimum overhead. To catch infrequent errors, you could connect all of the sources to a TraceEventSink for later analysis. Or, if there's a critical failure happening on a mission-critical server, you can quickly tie selected components into WMI for real-time monitoring.

Of course, all of these configuration files are in XML. There are several files that configure the overall operation of EIF, but for the most part, you'll work with an individual application's EnterpriseInformation.config file, which is stored in the same folder as the application's executable file. Sections in this file include:

A Simple Example

After you've installed all of the pieces, it's a good idea to build a simple application to make sure everything works. To do this, I created a C# Windows application named EIFTest with a single form. I placed two buttons, btnTrace and btnAudit, on the form. I then added references to the appropriate libraries, as well as using statements:

using System.ComponentModel;   
using Microsoft.EnterpriseInstrumentation;
using Microsoft.EnterpriseInstrumentation.Schema;

The next step is to add an Installer class to the form, inside of the project's namespace. This is necessary to get the application hooked up to the EIF after it's compiled. The Installer class just derives from a class supplied by the EIF, and doesn't contain any code. One tip: put this class after the form's own class to avoid confusing the form designer:

public class MyProjectInstaller : ProjectInstaller {}

Then I added code to translate button clicks into events from the default Application event source:

private void btnTrace_Click(object sender, System.EventArgs e)
  TraceMessageEvent.Raise("Tracing message");

private void btnAudit_Click(object sender, System.EventArgs e)
  AuditMessageEvent.Raise("Recording an audit record");

At this point, I built the solution. This creates the executable, but doesn't hook up the EIF bits. To do that, you need to drop out to a Visual Studio .NET command prompt, switch to the folder containing the .exe file, and run it through the installutil utility:

 installutil EIFTest.exe

You'll know this process completed correctly if it creates an EnterpriseInformation.config file in the same folder as the application. The next step is to open that file. Most of what you need is already in there, but you'll need to define a filter to hook the sources up to the sinks. This filter makes all events available to all sinks:

<filter name="defaultSoftwareElementFilter"
  description=" A default filter for the Software Element event sources.">
   <eventCategoryRef name="All Events">
      <eventSinkRef name="wmiSink" />
      <eventSinkRef name="traceSink" />
      <eventSinkRef name="logSink" />

That's all there is to it -- except for testing the application, of course. I ran the application and clicked the buttons a few times. Figure 2 shows the events in the Windows event log, and Figure 3 shows the trace log opened in the Trace Viewer application that comes with the EIF.

Events in the event log
Figure 2. Events in the event log
Events in the trace log
Figure 3. Events in the Trace Log

The Rest of the Picture

That should be enough to give you the overall flavor of the EIF, and to let you decide whether to evaluate it for your own applications. But there are other aspects that I don't have space to cover in this article; chief among these is request tracing, which allows you to tag a business object and to trace only events from that object as it moves along in your application. There are some limits to request tracing (it won't cross a web-service or MSMQ boundary, for example), but it can provide a powerful way to correlate events across different tiers of your application. EIF also lets you extend the information carried by an event through creating a custom WMI schema, and the help file contains important information on security.

Overall, the EIF provides a robust and flexible way for sysadmins, testers, and developers to share information on a running application. I frankly don't understand why Microsoft is keeping this framework in the dark. It seems to me that challenging J2EE in the enterprise would be better served by widely disseminating such key technologies. But if you've got a distributed application and a subscription to MSDN Universal, you should plan on setting aside a few days to evaluate integrating EIF with your application.

Mike Gunderloy is the lead developer for Larkware and author of numerous books and articles on programming topics.

Return to ONDotnet.com

Copyright © 2009 O'Reilly Media, Inc.