How to do ETW logging from .NET application

Sergei Meleshchuk - blog 

Contents

Introduction. 1

Sessions and providers. 1

Sample tracing application. 1

Starting tracing session. 2

Stopping and decoding tracing session. 3

 

 

Introduction

ETW, Event tracing for Windows, provides strategic benefits like:

-          You can log to same file from different threads and processes,

-          Extremely fast,

-          Tailing log records never lost, even your application crashes without warning,

-          You can turn tracing on and off, change level or set of tracing components, without restarting the application

-          And so on.

There is a small penalty – namely, you have to decode trace files.

.NET 3.5 provides tracing facilities for ETW. This post is a short reference of how to use the ETW in .NET.

Sessions and providers

You application will be the ‘trace provider’ (see example code about how to advertize the provider). Exposing provider is not enough to start tracing: you have to use one of the ETW command line utilities to actually enable tracing. Of course, this can be done from code; in the latter case you need some interop-ing and I am not writing about this here.

Now, to set up ETW tracing, you have to:

-          Author application appropriately:

o   Register the listener, all as usual

o   Create trace session via e.g. logman utility

o   Start session

To decode the trace file, you have to:

-          Close tracing session via logman utility

-           Decode the log file via another utility, tracerpt.

The remaining part of this post provides details.

Sample tracing application

 

using System;

using System.Diagnostics;

using System.Diagnostics.Eventing;

 

namespace EtwSample

{

    class Program

    {

        private static Guid providerId =

            new Guid("{A11a0820-c24b-428c-83e2-26b41091702e}");

        static void Main(string[] args)

        {

 

            EventProviderTraceListener listener =

                new EventProviderTraceListener(providerId.ToString());

            TraceSource source =

                new TraceSource("MyProvider", SourceLevels.All);

            source.Listeners.Add(listener);

            source.TraceData(

                TraceEventType.Warning | TraceEventType.Start, 2,

                new object[] { "abc", "def", true, 123 });

 

            /* Uncommen below if you want more fancy logging ...

            source.TraceEvent(

                TraceEventType.Warning, 12, "Provider guid: {0}",

                new object[] { providerId });

            source.TraceInformation(

               "string {0}, bool {1}, int {2}, ushort {3}",

               new object[] { "abc", false, 123, (UInt32)5 });

             * */

            for (int i = 0; i < 100; i++)

            {

                source.TraceInformation(

                    "This is sample trace record " + i);

            }

            source.Close();

        }

    }

}

 

Starting tracing session

1.       Pre-create logging directory, such as c:\logs

2.       On Vista or Server 2008, open elevated command window and type:

logman create trace mysession -o c:\logs\mylog -p "{A11a0820-c24b-428c-83e2-26b41091702e}"
where the GUID is the same you have in the code line
private static Guid providerId.
Other (red) parts of the command are arbitrary names.

3.       Start tracing session using the command (for example):
logman start mysession

Stopping and decoding tracing session

1.       Stop session via command
logman stop mysession

2.       Decode log file
tracerpt c:\logs
\mylog_000001.etl

As a result of the decoding, you have, in the current directory, 2 files:


dumpfile.xml – contains your decoded trace file

Summary.txt – some statistical information