Reputation: 1171
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();
}
}
Upvotes: 15
Views: 19106
Reputation: 1126
I did not have OperationIdTelemetryInitializer
in my TelemetryConfiguration .Active.TelemetryInitializers
.
But this provides me with the current operation id:
System.Diagnostics.Activity.Current.RootId
https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/504
Upvotes: 21
Reputation: 146
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 { }
Upvotes: 11
Reputation: 1171
You can get this value by sending a piece of telemetry and then reading back the operation id from the telemetry object. Not elegant, but it works.
[HttpPost]
public async Task<IActionResult> Post([FromBody]MyPostDataClass MyPostData)
{
var dummyTrace = new TraceTelemetry("hello", SeverityLevel.Verbose);
mTelemetryClient.TrackTrace(dummyTrace);
string opId = dummyTrace.Context.Operation.Id;
return Ok();
}
Upvotes: 0
Reputation: 25126
Asp.Net core package has an OperationIdTelemetryInitializer
(see github) which tries to set this from a request. Hypothetically if you have request tracking and this telemetry initializer turned on, everything that happens in that request should have an Operation.Id set.
if that isn't working for you, you could create your own custom TelemetryInitializer
to set it however you need, or, in the place where you do find it to be null, you could just set it there, and all things in that context should then have that id.
Upvotes: 1