logging - 如何将 npgsql 日志输出重定向到 log4net 记录器?

标签 logging log4net npgsql

是否可以将 npgsql 日志输出重定向到 log4net 记录器?从 npgsql 源代码来看,它看起来像是直接记录到 stdout/stderr 或指定文件(使用 NpgsqlEventLog 上的静态属性)。有没有办法将登录路由到 log4net?

最佳答案

我就是这样做的,看起来效果还不错。请注意,我将注销命令拆分到一个单独的附加程序,因为它变得非常冗长......

首先,在对 Npgsql 进行任何其他调用之前添加此内容:

NpgsqlLogManager.Provider = new Log4NetNpgsqlLoggingProvider("NpgsqlDefaultLogger")
{
    CommandLoggerName = "NpgsqlCommandLogger"
};

现在您需要添加日志记录提供程序类:

using System;
using Npgsql.Logging;

namespace Util.Npgsql
{
    public class Log4NetNpgsqlLoggingProvider : INpgsqlLoggingProvider
    {
        public string DefaultLoggerName { get; }
        public string CommandLoggerName { get; set; }

        public Log4NetNpgsqlLoggingProvider(string defaultLoggerName)
        {
            if (defaultLoggerName == null) throw new ArgumentNullException(nameof(defaultLoggerName));
            DefaultLoggerName = defaultLoggerName;
        }

        public NpgsqlLogger CreateLogger(string name)
        {
            switch (name)
            {
                case "Npgsql.NpgsqlCommand":
                    return new Log4NetNpgsqlLogger(CommandLoggerName ?? DefaultLoggerName);
                default:
                    return new Log4NetNpgsqlLogger(DefaultLoggerName);
            }
        }
    }
}

您还需要实际的记录器类:

using System;
using log4net;
using log4net.Core;
using Npgsql.Logging;

namespace Util.Npgsql
{
    public class Log4NetNpgsqlLogger : NpgsqlLogger
    {
        private readonly ILog _log;

        public Log4NetNpgsqlLogger(string name)
        {
            _log = LogManager.GetLogger(name);
        }

        public override bool IsEnabled(NpgsqlLogLevel level)
        {
            return _log.Logger.IsEnabledFor(GetLog4NetLevelFromNpgsqlLogLevel(level));
        }

        public override void Log(NpgsqlLogLevel level, int connectorId, string msg, Exception exception = null)
        {
            _log.Logger.Log(typeof(NpgsqlLogger), GetLog4NetLevelFromNpgsqlLogLevel(level), connectorId + ": " + msg, exception);
        }

        protected Level GetLog4NetLevelFromNpgsqlLogLevel(NpgsqlLogLevel level)
        {
            switch (level)
            {
                case NpgsqlLogLevel.Trace:
                case NpgsqlLogLevel.Debug:
                    return Level.Debug;
                case NpgsqlLogLevel.Info:
                    return Level.Info;
                case NpgsqlLogLevel.Warn:
                    return Level.Warn;
                case NpgsqlLogLevel.Error:
                    return Level.Error;
                case NpgsqlLogLevel.Fatal:
                    return Level.Fatal;
                default:
                    throw new Exception("Unknown Npgsql Log Level: " + level);
            }
        }
    }
}

关于logging - 如何将 npgsql 日志输出重定向到 log4net 记录器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10092512/

相关文章:

python - 使SocketHandler在python中登录文件

python - 将执行日志合并到报告中

Spring Boot @Aspect 日志记录

c# - 如何使用 Unity 2.0 注入(inject) Log4Net ILog 实现

c# - .Net Core 应用程序中的 Log4Net : LoggingEvent not set properly (LocationInformation porperties are set to "?")

C# NpgsqlCommand - AddWithValue 不是替代

c# - Npgsql/EF 6 - json 列

python - 如何根据当前日期创建文件结构?

log4net - 在 NServiceBus 初始化中为 Log4Net 设置 BufferSize

c# - 如何在 NpgsqlConnection 中设置编码