How to consume ETW events from C#

In my previous post I explained how to collect ETW events from URL Rewrite (or any other IIS provider) and then display those structured events in the Event Viewer. Now I want to show you how to collect ETW events using C#.

The .NET Framework 3.5 provides a new namespace System.Diagnostics.Eventing.Reader where you can find useful classes for publishing ETW events, but doesn’t provide a mechanism for consuming, so I had to write a class EventTraceWatcher for simplify things.

I want to use this class for tracking, in real time, all the URL Rewrite Events.

Setup Event Trace Session

The first thing to do is to setup the session, open “Reliability and Performance Monitor”, go to Event Trace Sessions and add a new Data Collector Set named “Rewrite”; my previous post has more detailed steps, once you create the collector set, go to its properties and add the provider “IIS: WWW Server” and the Keyword 0x400 (Rewrite) and set the Level to 5. Here is how it should be:

Trace Providers

Use stream mode “Real Time”

By default the Data Collector Set will write the collected events in the file system. Change it from File to “Real Time”. Your .NET Application will be listening those real time events. Open the data collector properties and in the Trace Session tab change this setting.

Trace Session

Make sure to start the Rewrite Collector once you are finish with this settings.

EventTraceWatcher class

The EventTraceWatcher class is very trivial to use, you need to provide the name of the Data Collector Set to it’s constructor (“Rewrite” in our example), hook the event “EventArrived” in your code and then just set the property Enabled to true to start the asynchronous processing of the ETW Events.

using System;
using Microsoft.Iis.Samples.Eventing;

class Program {
   
static void Main() {
       
try {
           
new Program().Run();
       
}
       
catch (Exception ex) {
           
Console.Error.WriteLine(ex);
       
}
   
}

   
private void Run() {
       
Guid RewriteProviderId = new Guid("0469abfa-1bb2-466a-b645-e3e15a02f38b");

       
using (EventTraceWatcher watcher = new EventTraceWatcher("Rewrite")) {

           
watcher.EventArrived += delegate(object sender, EventArrivedEventArgs e) {

               
if (e.EventException != null) {
                   
// Handle the exception
                    Console.Error.WriteLine(e.EventException);
                   
Environment.Exit(-1);
               
}

               
// Process only URL Rewrite events
                if (e.ProviderId != RewriteProviderId) {
                   
return;
               
}

               
// Dump the event name (e.g. URL_REWRITE_START, ABORT_REQUEST_ACTION, etc).
                Console.WriteLine("Event Name: " + e.EventName);

               
// Dump properties (e.g. RewriteURL, Pattern, etc).
                foreach (var p in e.Properties) {
                   
Console.WriteLine("\t" + p.Key + " -- " + p.Value);
               
}
               
Console.WriteLine();
           
};

           
// Start listening
            watcher.Enabled = true;
            // Listen events until user press <Enter>
           
Console.WriteLine("Press <Enter> to exit");
           
Console.ReadLine();
       
}
   
}
}

With this code you can write tools to help you to filter in real time information from IIS. Download the EventTraceWatcher class and feel free to modify it at your will.

No Comments