我希望某些异常作为警告而不是异常记录到应用程序见解中。不幸的是,我无法更改引发异常的代码,所以我改为创建了TelemetryProcessor(based on this answer)。
但是,此代码创建的TraceTelemetry
从未到达Application Insights。我检查了两个实时指标,并等待了几分钟,以便条目显示在搜索中。
我的猜测是我缺少某些内容,例如适当的上下文,但不确定要复制什么。 Context
属性是只读的,所以我不能简单地重用它。
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);
}
}
}
答案 0 :(得分:1)
这里的原因是,正如Peter指出的那样,它缺少上下文检测键。
您可以在Visual Studio中调试代码(在自定义遥测处理器类中设置检查点),然后在输出窗口中看到未配置检测键。截图如下:
请如下所示更改代码:
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);
}
}
答案 1 :(得分:0)
如果您将原始异常遥测中的所有数据复制到跟踪遥测中并进一步传递 - 它将被记录(关键是 Context.InstrumentationKey 和 Timestamp):< /p>
private ITelemetry ToTraceTelemetry(ExceptionTelemetry exceptionTelemetry)
{
var traceTelemetry = new TraceTelemetry(exceptionTelemetry.Message, SeverityLevel.Warning);
foreach (var telemetryProperty in exceptionTelemetry.Properties)
{
traceTelemetry.Properties.Add(telemetryProperty);
}
traceTelemetry.Timestamp = exceptionTelemetry.Timestamp;
traceTelemetry.Extension = exceptionTelemetry.Extension;
traceTelemetry.ProactiveSamplingDecision = exceptionTelemetry.ProactiveSamplingDecision;
traceTelemetry.Sequence = traceTelemetry.Sequence;
traceTelemetry.Context.InstrumentationKey = exceptionTelemetry.Context.InstrumentationKey;
traceTelemetry.Context.Flags = exceptionTelemetry.Context.Flags;
traceTelemetry.Context.Location.Ip = exceptionTelemetry.Context.Location.Ip;
traceTelemetry.Context.Cloud.RoleInstance = exceptionTelemetry.Context.Cloud.RoleInstance;
traceTelemetry.Context.Cloud.RoleName = exceptionTelemetry.Context.Cloud.RoleName;
traceTelemetry.Context.Component.Version = exceptionTelemetry.Context.Component.Version;
traceTelemetry.Context.Device.Id = exceptionTelemetry.Context.Device.Id;
traceTelemetry.Context.Device.Model = exceptionTelemetry.Context.Device.Model;
traceTelemetry.Context.Device.OemName = exceptionTelemetry.Context.Device.OemName;
traceTelemetry.Context.Device.OperatingSystem = exceptionTelemetry.Context.Device.OperatingSystem;
traceTelemetry.Context.Device.Type = exceptionTelemetry.Context.Device.Type;
traceTelemetry.Context.Operation.Id = exceptionTelemetry.Context.Operation.Id;
traceTelemetry.Context.Operation.CorrelationVector = exceptionTelemetry.Context.Operation.CorrelationVector;
traceTelemetry.Context.Operation.Name = exceptionTelemetry.Context.Operation.Name;
traceTelemetry.Context.Operation.ParentId = exceptionTelemetry.Context.Operation.ParentId;
traceTelemetry.Context.Operation.SyntheticSource = exceptionTelemetry.Context.Operation.SyntheticSource;
traceTelemetry.Context.Session.Id = exceptionTelemetry.Context.Session.Id;
traceTelemetry.Context.Session.IsFirst = exceptionTelemetry.Context.Session.IsFirst;
traceTelemetry.Context.User.Id = exceptionTelemetry.Context.User.Id;
traceTelemetry.Context.User.AccountId = exceptionTelemetry.Context.User.AccountId;
traceTelemetry.Context.User.AuthenticatedUserId = exceptionTelemetry.Context.User.AuthenticatedUserId;
traceTelemetry.Context.User.UserAgent = exceptionTelemetry.Context.User.UserAgent;
return traceTelemetry;
}
然后调用它:
public void Process(ITelemetry item)
{
if (item is ExceptionTelemetry exceptionTelemetry
&& other_condition)
{
item = ToTraceTelemetry(exceptionTelemetry);
}
Next.Process(item);
}