Adding custom properties for each request in Application Insights metrics

主宰稳场 提交于 2019-12-17 10:38:11

问题


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 ?

回答1:


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




回答2:


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.




回答3:


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.




回答4:


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;
}



回答5:


In that doc, scroll down a few lines to where it talks about creating an implementation of IContextInitializer. You can call that in any method that will be called before telemetry starts rolling.

Your custom properties will be added to all events, exceptions, metrics, requests, everything.



来源:https://stackoverflow.com/questions/29036729/adding-custom-properties-for-each-request-in-application-insights-metrics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!