When can I get an Application Insights operation id?

Iain Brown picture Iain Brown · Aug 25, 2016 · Viewed 7.2k times · Source

I have a AspNetCore web app that writes to EventHub and a webjob that reads from it. I'd like the telemetry from both parts of this transaction to have the same operation id in Application Insights.

So, when I'm about to send the data to EventHub I try to pull the operation id out of the TelemetryClient, e.g.

var myOperationId = MyTelemetryClient.Context.Operation.Id;

But this always gives me null. I found this article and tried using

var request.HttpContext.Items["Microsoft.ApplicationInsights.RequestTelemetry"] as RequestTelemetry;

But again null. Any pointers on a way I can extract this value when I need it?

My code looks like this:

public class Startup
{
    public void ConfigureServices( IServiceCollection IServices )
    {
        var builder = TelemetryConfiguration.Active.TelemetryProcessorChainBuilder;
        builder.Use((next) => new MyTelemetryProcessor(next));
        builder.Build();

        var aiOptions = new Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions();
        aiOptions.EnableQuickPulseMetricStream = true;

        IServices.AddApplicationInsightsTelemetry( Configuration, aiOptions);
        IServices.AddMvc();
        IServices.AddOptions();

        TelemetryClient AppTelemetry = new TelemetryClient();
        AppTelemetry.InstrumentationKey = InsightsInstrumentationKey;
        IServices.AddSingleton(typeof(TelemetryClient), AppTelemetry);
    }
    public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory )
    {
        app.UseApplicationInsightsRequestTelemetry();
        app.UseApplicationInsightsExceptionTelemetry();

        app.UseMvc();

        var configuration = app.ApplicationServices.GetService<TelemetryConfiguration>();
        configuration.TelemetryInitializers.Add(new MyTelemetryInitializer());
    }
}

[Route("[controller]")]
public class MyController
{
    private readonly TelemetryClient mTelemetryClient;

    public MyController(
        TelemetryClient TelemetryClientArg)
    {
        mTelemetryClient = TelemetryClientArg;
    }

    [HttpPost]
    public async Task<IActionResult> Post([FromBody]MyPostDataClass MyPostData)
    {
        string telemetryId = mTelemetryClient.Context.Operation.Id; // this is null

        return Ok();
    }
}

Answer

Russell Seamer picture Russell Seamer · Dec 9, 2016

Think I finally cracked this without creating unwanted telemetry. The following is for AspNetCore, but should translate as long as the operation id initializer is available:

var operationId = default(string);
try
{
    var telemetry = new RequestTelemetry();

    TelemetryConfiguration
        .Active
        .TelemetryInitializers
        .OfType<OperationIdTelemetryInitializer>()
        .Single()
        .Initialize(telemetry);

    operationId = telemetry.Context.Operation.Id;

}
catch { }