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.
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?
I found a solution, might not be the prettiest but at least it seems to work.
I created a statically accessible AsyncLocal
instance to hold the RequestTelemetry object for each thread.
public class RequestVariables
{
public static AsyncLocal<RequestTelemetry> RequestTelemetry = new AsyncLocal<RequestTelemetry>();
}
I set the value of RequestVariables.RequestTelemetry
in an ITelemetryInitializer
public class RequestTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
if (telemetry is RequestTelemetry requestTelemetry)
RequestVariables.RequestTelemetry.Value = requestTelemetry;
}
}
Then I registered a small middleware in the Startup.Configure(...)
method which fetches the RequestTelemetry
instance that was set by the ITelemetryInitializer
and adds the request headers to it.
app.Use((context, next) =>
{
var requestTelemetry = RequestVariables.RequestTelemetry.Value;
if (requestTelemetry?.Context == null) return next();
foreach (var header in context.Request.Headers)
{
if (!requestTelemetry.Context.Properties.ContainsKey(header.Key))
requestTelemetry.Context.Properties.Add(header.Key, header.Value.First());
}
return next();
});