Microsoft.Diagnostics.Tracing.EventSource is now RC on NuGet.org

Microsoft.Diagnostics.Tracing.EventSource is now RC on NuGet.org

Rate This
  • Comments 24

We are announcing the RC of 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.

Over the past several months we’ve been working on addressing feedback and extending the value proposition delivered by the EventSource NuGet release. Today I’m happy to announce the RC release of the EventSource package, and its new companion package EventRegister.

So, what’s new in RC?

Here’s a summary of the changes we’ve made:

  • EventSource build-time validation for everybody: with this release we’re including a new NuGet package, EventRegister. It enables build time validation for projects containing all variations of event source.

  • EventSource incremental improvements: improved handling for formatting strings, additional validation rules, and transparency attribute parity with mscorlib.

EventSource build-time validation for everybody

We’ve received feedback that the build-time validation included in the beta release of EventSource was providing a significant benefit to anybody that was defining their own event source. This feedbackw as the same for users of the EventSource NuGet package version and the system one (System.Diagnostics.Tracing.EventSource). As a result, we have released this functionality in the EventRegister NuGet package, which can be referenced from any project that uses some variation of EventSource. And, in order to maintain a seamless experience for the users of the NuGet EventSource package, EventSource is a dependent on EventRegister, so you’ll only need to add a reference to the EventSource package, and you’ll get validation/registration pulled in transparently.

We’ve also improved the validation experience. EventRegister will now report all validation failures for each event source type defined in your projects, instead of simply stopping at the first error it encounters. Here’s some sample output you may get in your error tool window:

EventSource validation results showing up in Visual Studio

And while we were working on the build system we’ve made some changes to the targets file to improve the clean build and incremental build experience. Extensibility points are now provided for projects that use EventRegister, so you can customize the behavior of the validation tool by defining relevant properties in the referencing project. Please find the details in the _EventRegisterUserGuide.docx included with the package.

Another notable improvement for the EventRegister package is that it now supports additional project types, in particular Portable Class Library projects and Windows Store projects.

EventSource incremental improvements

This release of EventSource adds other improvements:

  • Supports EventRegister’s full type validation
  • Addresses string formatting issues for the EventAttribute.Message property
  • Enforces more EventSource validation rules
  • The transparency attributes on the NuGet version of EventSource were changed so that it corresponds to the in-box version System.Diagnostics.EventSource. This fixed some cases where our security system wouldn’t let you use the NuGet version while you could use the in-box version. For more details, see MSDN.

What else does EventSource do?

Everything that was covered in the original Beta announcement relating to the EventSource core functionality still applies. Here are the highlights:

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 -- “Samples\EventSourceDemos\EventLog” – and yours would be similar. Your app events might show up under a node such as: “MyCompany\MyApp”

EventLog Demo showing in Windows Event Log

The following code 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 ETW 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 operation 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>.etwManifest.man
  • <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:"<FullPathToEtwManifestDllFile>"
    /mf:"<FullPathToEtwManifestDllFile>"

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.

Sample code

This release includes an update for the EventSource samples NuGet package. The easiest way to use the samples is to create a new console application 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.

What next?

Today, we’ve shipped the release candidate of Microsoft.Diagnostics.Tracing.EventSource and Microsoft.Diagnostics.Tracing.EventRegister packages. We plan to release a stable 1.0 package by the end of the year, but that will depend on the feedback we receive based on this RC release.

As always we’re looking forward to your feedback, so please let us know what you think. Let us know what works well for you and what other capabilities you’d like to see in the future in either of the packages released.

Leave a Comment
  • Please add 5 and 1 and type the answer here:
  • Post
  • I really like the new EventSource with EventRegister. What I do not like is the extra resource dll if you ever want to localize your ETW messages which will never happen. I wish there would be a way to register my eventsource with a dynamically generated manifest each time I instantiate my provider at runtime. Now I have embedded EventRegister as resource to call it at runtime which works nicely but still feels wrong. To prevent cluttering the GAC with dynamically generated files I copy my assembly and the tool and EvenSource.dll to %TEMP%\EventManifests to do the registration there. That works quite nicely. I wish there would be a way without resource dlls. I can register the EventSource with the plain assembly which works most of the time except if I want to get stack traces for my events then WPA will not be able to decode them.

  • Great to see improvements being added to this (both here and in 4.5.1).

    Thanks!

  • Dear .NET code analysis team,

    Sorry for posting this here. But I just want to know if any of dotnet guys respect CA2000 like below?

    ```csharp

    private static readonly ErrorListProvider ErrorListProvider = new ErrorListProvider(EditorExtensionsPackage.Instance)

    {

       ProviderName = "Unused CSS Browser Link Extension",

      ProviderGuid = new Guid("5BA8BB0D-D518-45ae-966C-864C536454F2")

    };

    ```

    the above code gives us warning and suggests us to make it like:

    ```csharp

    private static readonly ErrorListProvider ErrorListProvider = InitializeErrorListProvider();

    private static ErrorListProvider InitializeErrorListProvider()

    {

       ErrorListProvider errorListProvider = null;

       ErrorListProvider temp = null;

       try

       {

           temp = new ErrorListProvider(EditorExtensionsPackage.Instance);

           temp.ProviderName = "Unused CSS Browser Link Extension";

           temp.ProviderGuid = new Guid("5BA8BB0D-D518-45ae-966C-864C536454F2");

           errorListProvider = temp;

           temp = null;

           return errorListProvider;

       }

       finally

       {

           if (temp != null)

           {

               temp.Dispose();

           }

       }

    }

    ```

    Even though ErrorListProvider field will never throw an exception. Please fix the test or provide a sleek, similar to `using` syntax for this kind of chore, where we need to set the value without disposing it.

    Thank you.

  • Ops, I didn't realized that this comment area doesn't support markdown. Interestingly, we were having this discussion about CA2000 over a github commit for WebEssential extension for Visual Studio project's markdown feature: //github.com/SLaks/WebEssentials2013/pull/6

    Would be nice if we get git-flavored markdown (help.github.com/.../github-flavored-markdown) in the most notorious comment box (product of Telligent I presume). 8-)

    Come on guys, you can use Mads Kristensen's MiniBlog (github.com/.../MiniBlog), and use the comment system of your choice. ; -)

  • This is perfect timing for me, thanks! A couple of questions about the EventLogEventSource example:

    Why are the manifest files copied to C:\ProgramData\EventSourceSamples before being registered? Could they just stay with the program? Are those files needed after registration?

    The "SimulateInstall" and "SimulateUninstall" methods -- why are these called "simulate"? What's the difference between what they're doing and what you'd "really" do in an app?

    Is there a way to query (hopefully without being elevated) whether the manifest is installed? I want my program to check it it's installed and install it if not.

    thanks,

    -josh

  • @Alois Kraus: One of the design goals of EventSource is that you should only need to register the manifest and the DLL if your event source is using channel support (event log). That being said, there are some cases where the current release of the Windows Performance Toolkit does not recognize or simply misses ETW events fired by an event source. These issues should be fixed in an upcoming release of the toolkit. In the meantime you can try collecting the trace with the latest version of PerfView that will be published very soon (just make sure you "merge" the trace) and view it in WPA.

  • @Josh Santangelo: Yes, the DLL file is needed after registration. The "Local Service" account must have read access to the files (note that “Local Service” is by default a member of at least “BUILTIN\Users”, “NT AUTHORITY\Authenticated Users” so ensuring that one of these groups has read access to the file will ensure everything works as expected).

    > The "SimulateInstall" and "SimulateUninstall" methods -- why are these called "simulate"? What's the difference between what they're doing and what you'd "really" do in an app?

    The expectation is that the copying/deployment of the DLL and Manifest files as well as the wevtutil registration step are operations performed by a setup program, not by the application itself. Note that %ProgramFiles% or %ProgramData% have the appropriate ACLs by default, so that simply copying the manifest and DLL to a location under these folders guarantees your code will work as expected with the event system).

    > Is there a way to query (hopefully without being elevated) whether the manifest is installed?

    You can use the logman command for this: "logman query providers <your_provder_name_or_guid>"

  • @Adeel

    CA2000 is one of the last warning I put in ignore list. Usually in an medium sized project, I end up quite some instances of this warning, which need suppression. For static properties, such as your situation, you can't suppress the warning with SuppresMessage attribute right away, you would have to ignore this warning in ruleset file.

    Markdown with preview in MSDN blogs comments is a good idea. +1520!!!! Thanks to stackoverflow, markdown is not "technical" anymore.

  • It would be cool to provide a method in the eventsource class and the eventregister tool to create for the event providers corresponding wprp files to be able to easily record traces.

    I would like to see 3 different types of wprp profiles

    1. LogEvent: Enable Process Thread+Loader + own event provider

    2. LogEvent+CallStacks + NGen pdb creaton: Enable Process Thread+Loader + own event provider:::'stack' + CLR JIT events for dynamically generated code + a NGen rundown when stopping the trace session

    3. LogEvent + CallStacks: Same as before but without the NGen rundown which can take a long time for heavy server apps.

    The last one is useful if you record on a stable baseline several scenarios but you want to get your results fast. The Ngen cache may be working but I found it way too slow to call ngen thousands of times only to find that for this module the pdb is already there. It would be easier to deploy the pdbs besides the ngen dll directly so you can lookup the pdbs in a reliable and fast way without the overhead of calling an extra process.

  • @Alois Kraus

    WPRP files are something associated with WPR/WPA not ETW/EventSource in general and I have forwarded you feedback to that team.    In the mean time the scenarios you wish to collect can be done with PerfView reasonably easily (even if you want to use WPA to look at the data).   To collect just an EventSource called 'MySource' you would do

    PerfView collect /Zip:false /onlyProviders=*MySource

    If you want process events (so you get process names) do

    PerfView collect /Zip:false /onlyProviders=*MySource /KernelEvents:Process

    To collect with stacks (automatically collects the process image and JIT events to decode the stacks)

    PerfView collect /Zip:false /onlyProviders=*MySource:*:*:stacks

    This will put the NGEN PDBs into the first symbol cache in your _NT_SYMBOL_PATH variable or %temp%\symbols if you did not define one.   The upshot her is that if you define a good _NT_SYMBOL_PATH WPA should 'just work'

    Finally if you don't want the NGEN PDBs generated do

    PerfView collect /Zip:false  /NoNGenRundown /onlyProviders=*MySource:*:Verbose:stacks

    Eventually we will get WPA to know about ZIPed ETL files, at which point the /Zip:false will not be needed in the instructions above.  

    PerfView is really quite an good ETW data collector (It has lots of interesting options for stopping when various events (like a perf-counter going out of bounds), and is VERY easy to deploy (exactly one EXE), automatically ZIPs for easy network transport and can be used in scripts easily.     Even if you use WPA for you analysis, PerfView is pretty nice for data collection (and no WPRP files!).  

  • To collect with stacks (automatically collects the process image and JIT events to decode the stacks)

    PerfView collect /Zip:false /onlyProviders=*MySource:*:*:stacks

    this doesn't work for me. In the log I see this:

    Error: Could not parse level specification *

  • @Andre.Ziegler: Indeed the level specification does not support '*'. Instead please try using 'Verbose' or '5' (without the quotes) like this:

    PerfView collect /Zip:false /onlyProviders=*MySource:*:Verbose:stacks

  • @CosminRadu

    ok, this works but has the same bug like xperf when I try to capture the usermode stacks. Instead of the name I see events with the Name Crimson:{GUID}.

    Also the captured stack is bad. It includes too much noise. As a workaround I now use the .Net class StackTrace to get better stacks (but filter out all data without filename to exclude CLR calls) and pass this to the Event.

  • I've just used the package to send ETW events to the WCF event channels (Microsoft-Windows-Application Server-Application), and I've faced some limitations that is :

    1 - In the EventSource.CreateManifestAnDescriptors method, the following code :

    if (eventAttribute.Opcode == EventOpcode.Info && eventAttribute.Task == EventTask.None)

    {

       eventAttribute.Task = (EventTask)65534 - eventAttribute.EventId;

    }

    forces me to manually reset the event metadatas descriptions, since the WCF manifest have a lot of events that have an Opcode equals to Info and a task equals to none, and I don't what the event source to overrides this.

    By the way, I wonder why the couple Opcode/Task have to be unique? Especially because many existing manifests does not respect this constraint.

    2 - It is not possible to customize the channel keyword, but I think it's dues to the more general restriction that is you cannot customize the channels at all. Hope it will be fixed in a future release too.

    3 - You cannot specify a custom session mask.

    So, in consequence, the package is really usefull when creating new event provider, but hard to use to interact with third party manifests. But anyway this version in far much better than the one provided by the Framework, and I'm now really close to convince my colleagues to use it instead of Log4Net or NLog :) Good job guys!

  • I see this drop does more EventSource validation at build time.  Are these checks different than the checks that the PnP SLAB EventSourceAnalyzer perform?

Page 1 of 2 (24 items) 12