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();
}
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.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