Wednesday, January 9, 2019

.NET Core 2.2: Runtime Events

In this post let’s go through one of the features which got introduced with .NET Core 2.2 which is the ability to capture .NET Core runtime events within your .NET Core application.

Prior to .NET Core 2.2, these CoreCLR events were unable to be consumed within your .NET Core application, it was only available to be observed in ETW (Event Tracing for Windows) on Windows or from LTTng on Linux.

With .NET Core 2.2, these events are getting routed through an EventListener, so within your EventListener, you can decide what to do with it. It basically doesn’t matter on which OS you are on, it works on all Windows/MacOS and Linux.

Let’s have a look at an example. I have created an ASP.NET Core Web API Application targetting .NET Core 2.2.
<Project Sdk="Microsoft.NET.Sdk.Web">
 
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
 
</Project>
There I have the following EventListener.
public class SimpleEventListener : EventListener
{
    private readonly ILogger<SimpleEventListener> _logger;
 
    public SimpleEventListener(ILogger<SimpleEventListener> logger)
    {
        _logger = logger;
    }
 
    // Called whenever an EventSource is created.
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        // Watch for the .NET runtime EventSource and enable all of its events.
        if (eventSource.Name.Equals("Microsoft-Windows-DotNETRuntime"))
        {
            EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)(-1));
        }
    }
 
    // Called whenever an event is written.
    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // Write the contents of the event to the console.
        _logger.LogInformation($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventName}");
 
        for (var i = 0; i < eventData.Payload.Count; i++)
        {
            string payloadString = eventData.Payload[i] != null ? eventData.Payload[i].ToString() : string.Empty;
            _logger.LogInformation($"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
        }
 
        _logger.LogInformation("\n");
    }
}

Now I am enabling the SimpleEventListener from Startup.ConfigureServices method.
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
 
    ServiceProvider provider = services.BuildServiceProvider();
    var simpleEventListener = new SimpleEventListener(provider.GetRequiredService<ILogger<SimpleEventListener>>());
}

That’s it. Now if you run the application, you should be able to see all the CoreCLR events.
image
.NET Core 2.2: Visual Studio on Windows: CoreCLR Events
I just ran the same application inside MacOS, it works the same.
image
.NET Core 2.2: Rider on MacOS: CoreCLR Events
Now, if I change the target framework to 2.1 and return the application, we can’t see CoreCLR events.
image
.NET Core 2.1: Visual Studio on Windows: No CoreCLR Events
This is some awesome piece of work.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment