Announcing the EventSource NuGet Package – Write to the Windows Event Log

.NET Team

We are announcing the EventSource NuGet package, which enables fast app tracing to the Windows Event Log, including in production. This post was written by Cosmin Radu, a software developer on the .NET Runtime team

We know that you want to build high-quality software. That can be a challenging task if your desktop or web app interacts with users in complex ways or reads unstructured input, as examples. An important quality tool is instrumentation, which makes diagnosing functionality and performance problems much easier.

Starting with the .NET Framework 4.5, you can use the System.Diagnostics.Tracing.EventSource class to add efficient, strongly typed events into your code. With those events in place, you can use a listener to record events, to a text file, for example. In this release, we have extended this API to enable you to write your EventSource events directly to the Windows Event Log. This feature works for processes running with either admin or user credentials.

The screenshot below illustrates the feature. We defined an EventSource named ‘Samples-EventSourceDemos-EventLog’, and marked some of its events with the ‘Channel=EventChannel.Admin’ property. That declaration tells the system that we wish those events to go to the windows event log, and this screenshot shows us inspecting the data in one of the events in the windows event viewer.


This release is a beta of Microsoft.Diagnostics.Tracing.EventSource Nuget Package. This package works on .NET Framework 4 and above. You may notice that we have adopted the Microsoft namespace instead of the System one to avoid collision. If you are already use EventSource, in the System namespace and want to take advantage of this new feature, we recommend that you switch your ‘using’ statements for your app to Microsoft.Diagnostics.Tracing.

Along with the EventSource NuGet package we have provided an EventSource samples NuGet package. We thought that NuGet could be a good way to deliver sample code, too, so we are trying that approach with this release.

How does this relate to ETW?

The EventSource class is integrated with the Event Tracing for Windows (ETW) subsystem. ETW includes a feature called ETW channels, which allows you to direct your ETW events to the Windows Event Log, without you needing to know anything about how to interact with event log APIs. This release builds on top of ETW channels, enabling you take advantage of that feature from EventSource, in your .NET code.

Review: Basic EventSource Usage

There are a number of good references for EventSource that I recommend: the MSDN documentation as well as some great blog entries by Vance Morrison.

Let’s dive right in with an example. A custom event source type definition will generally follow a simple pattern (outlined below): 

    [EventSource(Name = "Samples-EventSourceDemos-Minimal")]
    public sealed class MinimalEventSource : EventSource
        // Define singleton instance
        public static MinimalEventSource Log = new MinimalEventSource();

        // Define Event methods
        public void Load(long baseAddress, string imageName)
            WriteEvent(1, baseAddress, imageName);

The above definition enables your code to call MinimalEventSource.Log.Load() to fire ETW events. These events can be observed by either an ETW listener (generally out of process) or an in-process, user defined EventListener. You can already do this with the .NET Framework 4.5.

Sending Events to the Windows Event Log

Event log support is a new feature provided with this NuGet package. It enables you to specify one additional destination for EventSource events – an application-defined event log. That means that all of your events will show up in a part of the event log that is specific to your app.

In the screenshot below, you will see an area highlighted. That’s the part of the event log that our demo code writes to — “SamplesEventSourceDemosEventLog” – and yours would be similar. Your app events might show up under a node such as: “MyCompanyMyApp”.


The following is an example of an ETW event definition that takes advantage of this new feature.  

    [EventSource(Name = "Samples-EventSourceDemos-EventLog")]
    public sealed class MinimalEventSource : EventSource
        public static MinimalEventSource Log = new MinimalEventSource();

        [Event(1, Message = "{0} -> {1}", Channel = EventChannel.Admin)]
        public void Load(long baseAddress, string imageName)
            WriteEvent(1, baseAddress, imageName);

   To use this feature, you specify the channel you want to write to in the Channel property of the Event attribute. The Event attribute is associated with the ETW event method your event source defines. In the class above, that’s the Load method. 

The NuGet package supports the four predefined ETW channels that the Windows Event Log defines: Admin, Operational, Analytics and Debug (see the ETW channel documentation for more information). You can see how those show up in the screenshot above. We also used an existing ‘Message’ attribute to create a formatted string for our message.

With the above definition (and a registration step detailed later), the “Load” event will write an event to the “Admin” event log each time it is called. This log can be found in the “Event Viewer” tool under the node “Applications and Services Logs / Samples / EventSourceDemos / EventLog”. Notice that the three-element name specified in the EventSourceAttribute determines the location of the log.

In order for the windows event viewer to know that there is a new source of events to log, it is necessary that you register your EventSource with the operating system, typically when your application is deployed or installed. This operations requires administrator permissions. The artifacts needed for registration (a manifest file and a resource DLL) are generated at build time through a build step injected in your project (when you add the NuGet package reference).

Registering your EventSource

When you install the EventSource NuGet package, the build step previously mentioned generates the following files for each EventSource in your application:

  • <AssemblyName>.<EventSourceTypeName>
  • <AssemblyName>.<EventSourceTypeName>.etwManifest.dll.

These files need to be registered with the operating system to enable channel support. To do this you run the following command after the files are in their final deployed location:

wevtutil.exe im <EtwManifestManFile> /rf:"<EtwManifestDllFile>" /mf:"<EtwManifestDllFile>"

Once this registration command is executed, all subsequent calls to MinimalEventSource.Log.Load(), from any process on that machine, will automatically result in events in the Windows Event log.

Note: you can provide localized strings for your EventSource by using the LocalizationResources property on the EventSourceAttribute associated with your EventSource type.

Build-time Validation of User-defined EventSources

Build-time validation of the user defined EventSources provides early feedback into possible issues with the EventSource definition, issues that would otherwise surface only at runtime, as silent logging failures. The build time validation step is injected into your project as a post build step and may lead to build failures when EventSource issues are detected.

Sample code

As I mentioned, we have a sample that you can try, which we released as the EventSource samples NuGet package. For best results, create a new console applications called ‘DemoEventSource’ in Visual Studio and then reference the EventSource Samples NuGet package from that project. The source code is part of the package and the Readme.txt file will tell you how to wire up your main program to the sample code.

This sample was used to create the event log screenshot at the top of this post. You can see what the EventSource definition looked like, for that sample, in the screenshot below.



Please let us know what you think. We think that event log support is an important addition to EventSource. Please let us know about any other capabilities you would like to see in EventSource as well as any problems you encounter adopting this new feature.


Discussion is closed.

Feedback usabilla icon