Including Headers for Request Events with Application Insights

When working with Application Insights recently in an ASP.NET application, I suddenly realised that the HTTP request and response headers weren’t included in the request data that is automatically captured. Fortunately, Application Insights has a few handy extensibility points, and this post looks at how to use one of them to include selected request and response headers along with the request events.

Application Insights has an extension point using an ITelemetryInitializer interface. By implementing this interface, you can create a class that plugs into Application Insights and is called to initialise the telemetry data before it is sent to the service.

For this scenario I created the HeaderTelemetryInitializer class as shown below. This class has a couple of properties to allow you to specify which request/response headers you want to include. In the Initialize method, it then gets the specified request and response headers (with the appropriate null checks) and adds them as custom properties for the telemetry.

 

 
    public class HeaderTelemetryInitializer : ITelemetryInitializer
    {
        public List<string> RequestHeaders { get; set; }
        public List<string> ResponseHeaders { get; set; }

        public HeaderTelemetryInitializer()
        {
            RequestHeaders = new List<string>();
            ResponseHeaders = new List<string>();
        }

        public void Initialize(ITelemetry telemetry)
        {
            var context = HttpContext.Current;
            if (context == null)
            {
                return;
            }
            if (context.Request != null)
            {
                foreach (var headerName in RequestHeaders)
                {
                    var header = context.Request.Headers[headerName];
                    if (header != null)
                    {
                        telemetry.Context.Properties.Add($"request-{headerName}", header);
                    }
                }
            }
            if (context.Response != null)
            {
                foreach (var headerName in ResponseHeaders)
                {
                    var header = context.Response.Headers[headerName];
                    if (header != null)
                    {
                        telemetry.Context.Properties.Add($"response-{headerName}", header);
                    }
                }
            }
        }
    }

Now that we have an ITelemetryInitializer, we need to register it with Application Insights when the application starts up (e.g. in Global.asax or our Startup class etc depending on which frameworks we’re using):

 
            TelemetryConfiguration.Active.TelemetryInitializers.Add(
                new HeaderTelemetryInitializer
                {
                    RequestHeaders =
                    {
                        "Accept"
                    },
                    ResponseHeaders =
                    {
                        "Content-Type"
                    }
                });

 

With that in place, we can run the site again and we will see the custom properties emitted for request that include the header values we asked for.

The code above is also included in a gist for easy consumption.

Enjoy!