Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding request headers to Application Insights telemetry for Nancy application

I want to include headers in the request events in Application Insights and found the following post that has a solution for application with a HttpContext. I'm working with a Nancy application where the request headers are stored in the NancyContext. Problem is that Nancy doesn't provide a static accessor like HttpContext.Current so I wonder how I can solve it.

I've made two attempts without succeeding. The first was to build an ITelemetryInitializer like described in the link below but then I could not access the NancyContext.

https://blogs.msdn.microsoft.com/stuartleeks/2016/11/03/including-headers-for-request-events-with-application-insights/

My second attempt was to pass the NancyModule to a static function that added the request headers to the ITelemetryContext but then I could not get a hold of the current ITelemetryContext instead.

Has anyone else faced and solved this issue?

like image 814
OriginalUtter Avatar asked Sep 13 '25 01:09

OriginalUtter


2 Answers

Actually, there is an example for .NET Framework: https://blogs.msdn.microsoft.com/stuartleeks/2016/11/03/including-headers-for-request-events-with-application-insights/

In .NET Core, you just access HttpContext using IHttpContextAccessor instead of HttpContext.Current:

public class TelemetryHeadersInitializer : ITelemetryInitializer
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public List<string> RequestHeaders { get; set; }
    public List<string> ResponseHeaders { get; set; }

    public TelemetryHeadersInitializer(IHttpContextAccessor httpContextAccessor)
    {
        RequestHeaders = new List<string> { "Referer" }; //whatever you need
        ResponseHeaders = new List<string> { ... };
        _httpContextAccessor = httpContextAccessor;
    }

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

        var context = _httpContextAccessor.HttpContext;
        if (context == null) return;

        foreach (var headerName in RequestHeaders)
        {
            var headers = context.Request.Headers[headerName];
            if (headers.Any())
            {
                telemetry.Context.Properties.Add($"Request-{headerName}", string.Join(Environment.NewLine, headers));
            }             
        }
        foreach (var headerName in ResponseHeaders)
        {
            var headers = context.Response.Headers[headerName];
            if (headers.Any())
            {
                telemetry.Context.Properties.Add($"Response-{headerName}", string.Join(Environment.NewLine, headers));
            }
        }
    }
}

//Services.cs:
services.AddSingleton<ITelemetryInitializer, TelemetryHeadersInitializer>();

Also check: https://github.com/Microsoft/ApplicationInsights-aspnetcore/wiki/Custom-Configuration

like image 94
Liero Avatar answered Sep 14 '25 16:09

Liero


Your second approach should work, and you can use an existing extension method to get the current request telemetry, if there is one.

the method is method: HttpContextExtension.GetRequestTelemetry(https://github.com/Microsoft/ApplicationInsights-dotnet-server/blob/2a681f5399a6aaee554fa2d93a1d6447a8402fe1/Src/Web/Web.Shared.Net/HttpContextExtension.cs#L16)

that will give you back the current request telemetry for a given HttpContext, so you should be able to do:

 var requestTelemetry = HttpContext.Current?.GetRequestTelemetry();
 // add whatever you need to the request telemetry?

from inside your Nancy module?

like image 45
John Gardner Avatar answered Sep 14 '25 15:09

John Gardner