Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding custom properties for each request in Application Insights metrics

I d'like to add custom properties to metrics taken by Application Insights to each request of my app. For example, I want to add the user login and the tenant code, such as I can segment/group the metrics in the Azure portal.

The relevant doc page seems to be this one : Set default property values

But the example is for an event (i.e. gameTelemetry.TrackEvent("WinGame");), not for an HTTP request :

var context = new TelemetryContext();
context.Properties["Game"] = currentGame.Name;
var gameTelemetry = new TelemetryClient(context);
gameTelemetry.TrackEvent("WinGame");

My questions :

  1. What is the relevant code for a request, as I have no specific code at this time (it seems to be automatically managed by the App Insights SDK) : Is just creating a TelemetryContext sufficient ? Should I create also a TelemetryClient and if so, should I link it to the current request ? How ?
  2. Where should I put this code ? Is it ok in the Application_BeginRequest method of global.asax ?
like image 911
JYL Avatar asked Mar 13 '15 15:03

JYL


People also ask

What is custom events in application Insights?

In Application Insights, a custom event is a data point that you can display in Metrics Explorer as an aggregated count and in Diagnostic Search as individual occurrences. (It isn't related to MVC or other framework "events.") Insert TrackEvent calls in your code to count various events.

Should I use single or multiple application Insights resources?

As per the FAQ: use one instance: Should I use single or multiple Application Insights resources? Use a single resource for all the components or roles in a single business system. Use separate resources for development, test, and release versions, and for independent applications.

What is the best way to use application Insights?

After you set up Application Insights, monitor your app. Set up availability web tests. Use the default application dashboard for your team room, to track load, responsiveness, and performance. Monitor your dependencies, page loads, and AJAX calls.

Are application Insights deprecated?

Because the workspace-based Application Insights enhances your monitoring experience, we retire the classic Application Insights on 29 February 2024.


4 Answers

It looks like adding new properties to existing request is possible using ITelemetryInitializer as mentioned here.

I created sample class as given below and added new property called "LoggedInUser" to request telemetry.

public class CustomTelemetry : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;
        if (requestTelemetry == null) return;
        requestTelemetry.Properties.Add("LoggedInUserName", "DummyUser");

    }
}

Register this class at application start event. Example below is carved out of sample MVC application I created

 public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        TelemetryConfiguration.Active.TelemetryInitializers
    .Add(new CustomTelemetry());
    }
}

Now you can see custom property "LoggedInUserName" is displayed under Custom group of request properties. (please refer screen grab below)

Appinsight with custom property

like image 94
Jitendra Patil Avatar answered Sep 24 '22 08:09

Jitendra Patil


Related to the first question "how to add custom event to my request / what is the relevant code to a request", I think the main confusion here is related to the naming.

The first thing that we need to point out is that there are different kinds of information that we can capture with Application Insights:

  1. Custom Event
  2. Request
  3. Exception
  4. Trace
  5. Page View
  6. Dependency

Once we know this, we can say that TrackEvent is related to "Custom Events", as TrackRequest is related to Requests.

When we want to save a request, what we need to do is the following:

 var request = new RequestTelemetry();
 var client = new TelemetryClient();
 request.Name = "My Request";
 client.TrackRequest(request);

So let's imagine that your user login and tenant code both are strings. We could make a new request just to log this information using the following code:

public void LogUserNameAndTenant(string userName, string tenantCode)
{
    var request = new RequestTelemetry();

    request.Name = "My Request";
    request.Context.Properties["User Name"] = userName;
    request.Context.Properties["Tenant Code"] = tenantCode;

    var client = new TelemetryClient();
    client.TrackRequest(request);
}

Doing just a TelemetryContext will not be enough, because we need a way to send the information, and that's where the TelemetryClient gets in place.

I hope it helps.

like image 32
Pliyo Avatar answered Sep 25 '22 08:09

Pliyo


You can use the static HttpContext.Current's Items dictionary as a short term (near stateless) storage space to deliver your custom property values into the default telemetry handler with a custom ITelemetryInitializer

Implement handler

class AppInsightCustomProps : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;
        // Is this a TrackRequest() ?
        if (requestTelemetry == null) return;

        var httpCtx = HttpContext.Current;
        if (httpCtx != null)
        {
            var customPropVal = (string)httpCtx.Items["PerRequestMyCustomProp"];
            if (!string.IsNullOrWhiteSpace(customPropVal))
            {
                requestTelemetry.Properties["MyCustomProp"] = customPropVal;
            }
        }
    }
}

Hook it in. Put this inside Application_Start in global.asax.cs

TelemetryConfiguration.Active.TelemetryInitializers.Add(new AppInsightCustomProps());

Program the desired custom property, anywhere in your request pipeline have something like

if (HttpContext.Current != null)
{
    HttpContext.Current.Items["PerRequestMyCustomProp"] = myCustomPropValue;
}
like image 40
DeepSpace101 Avatar answered Sep 24 '22 08:09

DeepSpace101


As mentioned by Alan, you could implement the IContextInitializer interface to add custom properties to ALL telemetry sent by Application Insights. However, I would also suggest looking into the ITelemtryInitializer interface. It is very similar to the context initializer, but it is called for every piece of telemetry sent rather than only at the creation of a telemetry client. This seems more useful to me for logging property values that might change over the lifetime of your app such as user and tenant related info like you had mentioned.

I hope that helps you out. Here is a blog post with an example of using the ITelemetryInitializer.

like image 27
amayer42 Avatar answered Sep 25 '22 08:09

amayer42