Azure Application Insights Role Name Nuget Package


I’ve been using Azure Application Insights to monitor micro-services.

Since I have many micro-services, it isn’t practical to have an Application Insight resource per service. Given that those micro-services interact with each other and I want to monitor those interactions, it makes sense to get all telemetry in one place.

The issue with that is to isolate the telemetry of each service when I want to gain insights on one service at the time.

The general guidance is to set the cloud_RoleName property on telemetry. That property is used by Application Map, among other things, to single out applications.

In order to do that with the .NET SDK, it is recommended to use Telemetry Initializer.

Implementing that in each of my micro-service is repetitive so I built the shared logic in a Nuget Package.

Here I’ll talk about the package, its implementation & how to use it.

The code for the package is on GitHub.

Using the Nuget Package

Using the package is quite straightforward:

  1. Install the package
  2. Add instrumentation key in the appsettings.json
  3. Add UseApplicationInsights on the web-host
  4. Add RoleNameInitializer to the telemetry initializers list

A few of those steps are done automatically when we use the Configure Application Insights wizard. As always, we prefer knowing what is going on. We’ll therefore refrain from wizardry.

Install the package

This one is trivial.

It is interesting to note that the package will bring the following package with it:

  • Microsoft.ApplicationInsights.AspNetCore (Application Insights SDK)
  • Microsoft.AspNetCore.Http.Abstractions

Add instrumentation key in the appsettings.json

The appsettings.json file should look like this:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ApplicationInsights": {
    "InstrumentationKey": "<MY KEY>"
  }
}

The important part is the ApplicationInsights section. The instrumentation key is found in the overview pane:

Instrumentation Key

Add UseApplicationInsights on the web-host

Typically, the Web Host is initialized in the Program.cs file. We should add UseApplicationInsights there, so it looks like this:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseApplicationInsights()
        .UseStartup<Startup>()
        .Build();

Optionally the instrumentation key can be passed in parameter to that method.

Add RoleNameInitializer to the telemetry initializers list

Now, inside the Startup.Configure object, we need to add:

TelemetryConfiguration.Active.TelemetryInitializers.Add(new RoleNameInitializer("<MY SERVICE NAME>"));

TelemetryConfiguration.Active.TelemetryInitializers belongs to the Microsoft Application Insights’ SDK while RoleNameInitializer belongs to our Nuget Package.

The mechanic of telemetry initializers is they are called one after the other with a telemetry object. They can then alter the telemetry object.

That’s it. Our telemetry should now be tagged with our service name.

Result in App Insights

We can see our telemetries is now segmented by role name. For instance, if we query:

requests |
distinct cloud_RoleName

We should see our service name in there.

This is true for all telemetry in the application (e.g. custom events).

Implementation

The implementation, i.e. the code of the NuGet Package is quite simple.

It boils down to one class, RoleNameInitializer:

/// <summary>Add a cloud role name to the context of every telemetries.</summary>
/// <remarks>
/// This allows to monitor multiple components and discriminate betweeen components.
/// See https://docs.microsoft.com/en-us/azure/application-insights/app-insights-monitor-multi-role-apps.
/// </remarks>
public class RoleNameInitializer : ITelemetryInitializer
{
    private readonly string _roleName;

    /// <summary>Construct an initializer with a role name.</summary>
    /// <param name="roleName">Cloud role name to assign to telemetry's context.</param>
    public RoleNameInitializer(string roleName)
    {
        if(string.IsNullOrWhiteSpace(roleName))
        {
            throw new ArgumentNullException(nameof(roleName));
        }

        _roleName = roleName;
    }

    void ITelemetryInitializer.Initialize(ITelemetry telemetry)
    {
        telemetry.Context.Cloud.RoleName = _roleName;
    }
}

The key is the initialize method. As mentioned above, this is called by the Microsoft Application Insights SDK on each telemetry.

Here we simply set the cloud role name.

Bonus feature: logging request body

Another telemetry initializer is implemented in the Nuget package: RequestBodyInitializer.

This initializer captures the body of a request. It needs to be used with care as it could use a lot of resources depending on request sizes.

This was based on a Stack overflow article.

It is a little trickier to use as it takes a IHttpContextAccessor in parameter. Thankfully, that component is dependency injected in ASP.NET core.

We therefore recommend adding the component to the services:

public class Startup
{
    //  ...

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // ...
        services.AddTransient<RequestBodyInitializer, RequestBodyInitializer>();
    }

This way, when it is constructed, it will get an IHttpContextAccessor.

We can then add it as a parameter to the Configure method and finally add it to the telemetry initializers list:

public void Configure(
    IApplicationBuilder app,
    IHostingEnvironment env,
    RequestBodyInitializer requestBodyInitializer)
{
    //  ...
    TelemetryConfiguration.Active.TelemetryInitializers.Add(new RoleNameInitializer("PasApi"));
    TelemetryConfiguration.Active.TelemetryInitializers.Add(requestBodyInitializer);

Summary

Changing the cloud role name isn’t rocket science but it can be repetitive.

We created a Nuget package to simplify that.

We hope that can be useful to any of you out there.

Advertisements

2 thoughts on “Azure Application Insights Role Name Nuget Package

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s