I want certain exceptions to be logged to application insights as warnings instead of exceptions. Unfortunately, I can't change the code that throws the exceptions, so I created a TelemetryProcessor instead (based on this answer).
However, the TraceTelemetry
created by this code never reaches Application Insights. I checked both the live metrics and waited a couple of minutes for the entries to show up in search.
My guess would be that I am missing some things like the proper context, but I am unsure what to copy. The Context
property is readonly, so I can't simply reuse it.
public class ExceptionTelemetryProcessor : ITelemetryProcessor
{
private ITelemetryProcessor Next { get; set; }
public ExceptionTelemetryProcessor(ITelemetryProcessor next)
{
Next = next;
}
public void Process(ITelemetry item)
{
if (item is ExceptionTelemetry exceptionTelemetry
&& exceptionTelemetry.Exception is Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException bhre
&& bhre.StatusCode == 408)
{
// Track exception as warning instead
var traceTelemetry = new TraceTelemetry(exceptionTelemetry.Exception.Message, SeverityLevel.Warning);
Next.Process(traceTelemetry);
}
else
{
Next.Process(item);
}
}
}
The reason here is that it lacks context instrumentation key as Peter points out.
You can debug your code(set checkpoint in your custom Telemetry Processor class) in visual studio, and in the output window, you can see the instrumentation key is not configured. Screenshot as below:
Please change your code like below:
public void Process(ITelemetry item)
{
if (item is ExceptionTelemetry exceptionTelemetry
&& other_condition)
{
// Track exception as warning instead
var traceTelemetry = new TraceTelemetry(exceptionTelemetry.Exception.Message, SeverityLevel.Warning);
//add this line of code to send the trace message.
new TelemetryClient().TrackTrace(traceTelemetry);
//Note that, you should remove the Next.Process() method here, or it will reproduce another same message with the above line of code
//Next.Process(traceTelemetry);
}
else
{
Next.Process(item);
}
}