You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure Service Fabric应用中捕获未捕获异常并记录至App Insights

当然可以搞定!在Azure Service Fabric里实现全局未捕获异常的捕获、记录到App Insights再重新抛出,得根据你的服务类型(是ASP.NET Core Web服务还是普通的无状态/有状态服务)来选对应的方案,我给你梳理几个常用的场景:

1. 针对ASP.NET Core类型的后端服务

如果你的后端是基于ASP.NET Core的Web服务,自定义异常处理中间件是最靠谱的方式——它能拦截所有请求链路里的未捕获异常,记录到App Insights后再重新抛出。

先写一个自定义中间件:

public class UnhandledExceptionLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<UnhandledExceptionLoggingMiddleware> _logger;
    private readonly TelemetryClient _telemetryClient;

    public UnhandledExceptionLoggingMiddleware(RequestDelegate next, ILogger<UnhandledExceptionLoggingMiddleware> logger, TelemetryClient telemetryClient)
    {
        _next = next;
        _logger = logger;
        _telemetryClient = telemetryClient;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        try
        {
            // 传递请求到下一个中间件
            await _next(httpContext);
        }
        catch (Exception ex)
        {
            // 把异常记录到App Insights,顺便加些服务上下文方便排查
            var exceptionTelemetry = new ExceptionTelemetry(ex);
            exceptionTelemetry.Properties["ServiceName"] = httpContext.Request.Host.Value;
            exceptionTelemetry.Properties["RequestPath"] = httpContext.Request.Path;
            _telemetryClient.TrackException(exceptionTelemetry);

            // 同时记到本地日志(可选)
            _logger.LogError(ex, "未捕获异常已上报至App Insights");

            // 重新抛出异常,让上层框架或Service Fabric处理后续逻辑
            throw;
        }
    }
}

然后在Program.cs里注册这个中间件注意要放在路由、端点等核心中间件之前,确保能捕获到所有异常:

// 注册自定义异常日志中间件
app.UseMiddleware<UnhandledExceptionLoggingMiddleware>();

// 其他中间件注册(比如路由、静态文件等)
app.UseRouting();
// ...
2. 针对非ASP.NET Core的Service Fabric服务(无状态/有状态)

如果是普通的无状态/有状态服务(比如只在RunAsync里跑业务逻辑),需要在服务的初始化和核心循环里做全局异常捕获,同时还要处理后台线程、Task的未观察异常。

处理RunAsync循环内的异常

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    var telemetryClient = new TelemetryClient(new TelemetryConfiguration("<你的App Insights Instrumentation Key>"));

    try
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            // 你的核心业务逻辑代码
            await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
        }
    }
    catch (Exception ex)
    {
        // 记录异常到App Insights,加上Service Fabric的上下文信息
        var exceptionTelemetry = new ExceptionTelemetry(ex);
        exceptionTelemetry.Properties["PartitionId"] = Context.PartitionId.ToString();
        exceptionTelemetry.Properties["ReplicaId"] = Context.ReplicaId.ToString();
        telemetryClient.TrackException(exceptionTelemetry);
        
        // 强制推送日志,避免进程退出前日志没发出去
        telemetryClient.Flush();
        await Task.Delay(TimeSpan.FromSeconds(2));

        // 重新抛出异常,让Service Fabric触发故障转移
        throw;
    }
}

捕获AppDomain和Task的全局未处理异常

在服务的OnInitialize方法里注册全局事件,覆盖线程池、后台Task的未捕获异常:

protected override void OnInitialize()
{
    base.OnInitialize();
    var telemetryClient = new TelemetryClient(new TelemetryConfiguration("<你的App Insights Instrumentation Key>"));

    // 捕获AppDomain级别的未处理异常
    AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
    {
        if (args.ExceptionObject is Exception ex)
        {
            telemetryClient.TrackException(ex);
            telemetryClient.Flush();
            Task.Delay(TimeSpan.FromSeconds(2)).Wait();
        }
    };

    // 捕获未被观察到的Task异常
    TaskScheduler.UnobservedTaskException += (sender, args) =>
    {
        telemetryClient.TrackException(args.Exception);
        telemetryClient.Flush();
        Task.Delay(TimeSpan.FromSeconds(2)).Wait();
        
        // 这里如果调用args.SetObserved()会阻止进程崩溃,但通常推荐让异常传播,触发Service Fabric的故障转移
        // args.SetObserved();
    };
}
3. 几个通用注意事项
  • 配置App Insights:确保你的服务已经通过配置文件(比如appsettings.json)或者环境变量正确设置了App Insights的Instrumentation Key,避免硬编码。
  • 补充上下文信息:记录异常时尽量添加服务名称、分区ID、请求参数等信息,后续排查问题会方便很多。
  • 日志推送时机:在进程可能退出的场景下,调用Flush()后最好加一点延迟,确保日志能成功发送到App Insights。

内容的提问来源于stack exchange,提问作者Slicc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:59:28