You need to enable JavaScript to run this app. 使用Npgsql的EnableRetryOnFailure时如何查看重试发生的日志或相关提示?
优惠活动
大模型
产品
解决方案
定价
更多

使用Npgsql的EnableRetryOnFailure时如何查看重试发生的日志或相关提示?

监控Npgsql EF Core重试事件的实现方案

你可以通过两种常用方式捕获EnableRetryOnFailure的重试触发事件,确认机制是否正常生效:

方法1:自定义执行策略(推荐,灵活性最高)

继承Npgsql官方的NpgsqlRetryingExecutionStrategy类,重写OnRetry方法注入自定义的日志、事件触发逻辑:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Npgsql;
using Microsoft.Extensions.Logging;

public class LoggingNpgsqlRetryingExecutionStrategy : NpgsqlRetryingExecutionStrategy
{
    private readonly ILogger _logger;

    public LoggingNpgsqlRetryingExecutionStrategy(
        ExecutionStrategyDependencies dependencies,
        int maxRetryCount,
        TimeSpan maxRetryDelay,
        ICollection<string> errorCodesToAdd)
        : base(dependencies, maxRetryCount, maxRetryDelay, errorCodesToAdd)
    {
        _logger = dependencies.Logger.Logger;
    }

    protected override void OnRetry(Exception exception, TimeSpan delay)
    {
        // 自定义日志输出,包含重试次数、延迟时长、故障原因
        _logger.LogWarning(
            "数据库临时故障触发重试,第{RetryCount}次重试,延迟{Delay}ms,错误信息:{Message}",
            RetryCount + 1,
            delay.TotalMilliseconds,
            exception.Message);
        
        // 如需对外暴露重试事件,可在这里触发自定义事件
        RetryTriggered?.Invoke(this, new RetryEventParams(RetryCount + 1, delay, exception));
        
        base.OnRetry(exception, delay);
    }

    // 自定义重试事件参数
    public class RetryEventParams : EventArgs
    {
        public int RetryCount { get; }
        public TimeSpan Delay { get; }
        public Exception Exception { get; }

        public RetryEventParams(int retryCount, TimeSpan delay, Exception exception)
        {
            RetryCount = retryCount;
            Delay = delay;
            Exception = exception;
        }
    }

    public static event EventHandler<RetryEventParams> RetryTriggered;
}

替换原来的EnableRetryOnFailure配置,注册自定义执行策略:

builder.Services.AddDbContext<你的上下文类名>(options =>
    options.UseNpgsql("你的数据库连接字符串", npgsqlOpts =>
    {
        // 替换原有EnableRetryOnFailure调用
        npgsqlOpts.ExecutionStrategy(dependencies => 
            new LoggingNpgsqlRetryingExecutionStrategy(
                dependencies,
                maxRetryCount: 5, // 保持和你之前配置的重试次数一致
                maxRetryDelay: TimeSpan.FromSeconds(30), // 保持和你之前配置的最大重试延迟一致
                errorCodesToAdd: null)); // 额外需要重试的PostgreSQL错误码,无额外需求传null即可
    }));

方法2:监听EF Core内置日志事件(无需修改原有执行策略配置)

EF Core本身会输出重试对应的日志事件,事件ID为CoreEventId.ExecutionStrategyRetrying,你可以直接通过日志过滤或者诊断监听器捕获:

日志过滤配置示例

builder.Services.AddLogging(logging =>
{
    // 开启EF Core Warning级别的日志即可收到重试通知
    logging.AddFilter("Microsoft.EntityFrameworkCore", LogLevel.Warning);
});

诊断监听器捕获示例(适合需要代码层面处理重试事件的场景)

using Microsoft.EntityFrameworkCore.Diagnostics;
using System.Diagnostics;

public class EfCoreRetryObserver : IObserver<KeyValuePair<string, object>>
{
    public void OnNext(KeyValuePair<string, object> value)
    {
        if (value.Key == CoreEventId.ExecutionStrategyRetrying.Name)
        {
            var eventData = (ExecutionStrategyRetryingEventData)value.Value;
            // 这里处理重试逻辑,比如上报监控、记录详细日志
            Console.WriteLine($"重试触发:第{eventData.RetryAttempt}次,延迟{eventData.Delay.TotalMilliseconds}ms,错误原因:{eventData.Exceptions.FirstOrDefault()?.Message}");
        }
    }

    public void OnError(Exception error) { }
    public void OnCompleted() { }
}

// 项目启动时注册观察者
DiagnosticListener.AllListeners.Subscribe(listener =>
{
    if (listener.Name == "Microsoft.EntityFrameworkCore")
    {
        listener.Subscribe(new EfCoreRetryObserver());
    }
});

功能验证

  • 测试时可以临时断开数据库网络,或者主动触发PostgreSQL可重试错误(比如序列化失败错误码40001、连接中断错误码57P01),查看是否有对应的重试日志/事件触发即可确认机制生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 14:06:08