Application Insights - How to add custom metric to your request information?

2.7k views Asked by At

This question is very similar to what I want to know. I've got a web api service on an azure cloud service with Application Insights configured. On the request information portal, that is generated automatically, I want to add a custom http header that's a part of the request into the information that is being logged with each request. The question is how do I do this?

I've tried using a telemetry initializer like below, but this fails (as in I don't see the information on the portal). I also added this in the global.asax TelemetryConfiguration.Active.TelemetryInitializers.Add(propertyTelemetryInitializer);

public class PropertyTelemetryInitializer : ITelemetryInitializer
{
    private readonly HttpContext httpContext;

    public PropertyTelemetryInitializer(HttpContext httpContext)
    {
        this.httpContext = httpContext;
    }

    public void Initialize(ITelemetry telemetry)
    {
        this.AddTelemetryContextPropertFromContextHeader(telemetry, "xyz");
        this.AddTelemetryContextPropertFromContextHeader(telemetry, "abc");
        this.AddTelemetryContextPropertFromContextHeader(telemetry, "123");
    }

    private void AddTelemetryContextPropertFromContextHeader(ITelemetry telemetry, string headerKey)
    {
        var requestTelemetry = telemetry as RequestTelemetry;

        telemetry.Context.Properties[headerKey] = this.httpContext.Request.Headers[headerKey] ?? string.Empty;
        telemetry.Context.Properties[headerKey] = this.httpContext.Request.Headers[headerKey] ?? string.Empty;
    }
}

Also is there a way to do this from the controller method itself? Something similar to the below (note: the below does not work)?

    [Route("api/Something")]
    [HttpGet]
    [ResponseType(typeof(Something))]
    public async Task<Something> GetSomething()
    {
        var requestTelemetry = new RequestTelemetry();
        this.AddCustomHeadersToRequestTelemetry(requestTelemetry);
        var result = await this.Service.GetSomethingAsync();
        requestTelemetry.Properties["result"] = result.ToString();
        return TypeMapper.Map<Model.Something, Something>(result);
    }


    /// <summary>
    /// Adds the custom headers to request telemetry.
    /// </summary>
    /// <param name="controller">The controller.</param>
    /// <param name="requestTelemetry">The request telemetry.</param>
    public static void AddCustomHeadersToRequestTelemetry(this ApiController controller, RequestTelemetry requestTelemetry)
    {
        if (controller == null)
        {
            throw new ArgumentNullException("controller");
        }

        if (requestTelemetry == null)
        {
            throw new ArgumentNullException("requestTelemetry");
        }

        requestTelemetry.Context.Properties["abc"] = controller.Request.GetABCFromHeader();
        requestTelemetry.Context.Properties["xyz"] = controller.Request.GetXYZFromHeader();
        requestTelemetry.Context.Properties["123"] = controller.Request.Get123FromHeader();
    }
1

There are 1 answers

0
Anastasia Black On BEST ANSWER

Using TelemetryInitializers is the right solution. Some comments:

  • var requestTelemetry = telemetry as RequestTelemetry;: you do not use requestTelemetry after that. I guess you wanted to check for null.
  • Adding telemetry initializer in the Active configuration should be fine. You can also consider moving it to the applicationinsights.config
  • Custom properties do not show up in the portal immediately. Have you tried to reopen IE after some time and check your request again?
  • Can you debug? Do you see that you get in your tememetry initializer? Do you see any AI specific traces in search?

Regarding your second question. Right now telemetry initializers are the only (official) way to get to the autogenerated RequestTelemetry (which is actually in the HttpContext). There are plans to make most of the classes in web public and eventually open source it. But there is no ETA yet. If you create and track request yourself you can add custom properties as you mentioned.

UPDATE: Starting from 2.0.0-beta3 autogenerated request telemetry is accessible though HttpContext extension method: System.Web.HttpContextExtension.GetRequestTelemetry