c# - 停止由 CancellationToken 生成的异常被 ApplicationInsights 报告

标签 c# asp.net-core azure-application-insights cancellation-token

我认为使用 CancellationToken 是个好主意在我的 Controller 中,像这样:

[HttpGet("things", Name = "GetSomething")]
public async Task<ActionResult> GetSomethingAsync(CancellationToken ct) {
    var result = await someSvc.LoadSomethingAsync(ct);
    return Ok(result);
}
问题是现在 Azure Application Insights 显示了一堆 System.Threading.Tasks.TaskCancelledException: A Task was canceled. 类型的异常。以及偶尔 Npgsql.PostgresException: 57014: canceling statement due to user request .这是我不需要的噪音。
Application Insights 使用标准方法注册为服务 - services.AddApplicationInsightsTelemetry(Configuration); .
尝试的解决方案
我想我可以进入应用程序管道并捕获上述异常,将它们转换为正常响应。我把下面的代码放在了不同的地方。它捕获任何异常,如果是 IsCancellationRequested,则返回一个虚拟响应。否则它会重新抛出捕获的异常。
app.Use(async (ctx, next) =>
{
    try { await next(); }
    catch (Exception ex)
    {
        if (ctx.RequestAborted.IsCancellationRequested)
        {       
            ctx.Response.StatusCode = StatusCodes.Status418ImATeapot;
        }
        else { throw; }
    }
});
这段代码的作用是改变响应。但是,异常仍会发送到 Application Insights。
要求
  • 我想要一个使用 RequestAborted.IsCancellationRequested 的解决方案试图捕捉特定的异常。原因是,如果我已经发现了一个抛出异常的实现,该异常不是源自 OperationCanceledException可能性存在还有其他人会做同样的事情。
  • 依赖失败是否仍然被记录并不重要,只是由于请求被取消而引发的异常不会。
  • 我不想在每个 Controller 方法中都有一个 try/catch。它需要放置在一个位置。

  • 结论
    我希望我了解报告异常的 Application Insights 机制。试验后,我觉得试图在应用程序管道中捕获错误不是正确的方法。我只是不知道是什么。

    最佳答案

    我能够用 TelemetryProcessor 解决这个问题。

    为了在处理器中访问 RequestAborted.IsCancellationRequested,需要通过调用 services.AddHttpContextAccessor() 使 HttpContext 服务可用。在 Startup.ConfigureServices 中。

    在处理器中,如果 IsCancellationRequested 为真,我会阻止处理任何异常遥测。下面是我的最终解决方案的一个简化示例,因为最终我意识到我需要对超出原始请求范围的依赖项和请求做一些更细微的工作。

    internal class AbortedRequestTelemetryProcessor : ITelemetryProcessor
    {
        private readonly IHttpContextAccessor httpContextAccessor;
        private readonly ITelemetryProcessor next;
    
        public AbortedRequestTelemetryProcessor(
            ITelemetryProcessor next, IHttpContextAccessor httpContextAccessor)
        {
            this.httpContextAccessor = httpContextAccessor;
            this.next = next;
        }
    
        public void Process(ITelemetry item)
        {
            if (httpContextAccessor.HttpContext?.RequestAborted.IsCancellationRequested == true 
                && item is ExceptionTelemetry)
            {
                // skip exception telemetry if cancellation was requested
                return; 
            }
            // Send everything else:
            next.Process(item);
        }
    }
    

    关于c# - 停止由 CancellationToken 生成的异常被 ApplicationInsights 报告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58615385/

    相关文章:

    c# - Linq to Entities over SQL Server 2005 上的 EF 4

    c# - 将字符串格式化为日期

    angular - 当 Web API 返回 void 时订阅 observable

    azure-application-insights - 除了Azure Portal之外,还有查看Application Insights日志的方法吗?

    c# - 使用多个 ServicePointManager.SecurityProtocol,它首先尝试什么?

    c# - 如果 else 语句不起作用

    c# - 在 MVC 程序中调用 Web API

    c# - 如何在 Azure Service Fabric ASP.NET Core 有状态服务中获取 PartitionInfo?

    azure - 在 Windows 应用商店应用程序中启动后如何停止收集遥测数据?

    c# - 如何在运行时将值添加到自定义维度 - Azure 应用程序见解