使用 NLog.Web.AspNetCore 的 NHibernate 日志记录

NHibernate logging using NLog.Web.AspNetCore

我已经浪费了将近一整天的时间来尝试通过 NLog.Web.AspNetCore 为 ASP.Net 核心项目制作 NHibernate 日志消息 – 但无济于事。我能找到的唯一示例是 hidden deep inside the NHibernate Git repository,但它不适用于现代版本的 Microsoft 日志记录库。更不用说它是一个非常粗略的解决方案,因为我必须 copy/paste 该文件夹中的两个辅助 类 以手动桥接 Microsoft 世界和 NHibernate 世界之间的记录器和记录器工厂。

有没有我没能找到的理智、现代、优雅的解决方案(或 NuGet 包)?我觉得我在这里遗漏了一些简单的东西,但就我的生活而言,我似乎无法让它发挥作用。

为清楚起见,我正在寻找一种通过 NLog 传输 NHibernate 自己的日志消息的方法,不是使用 NHibernate 将 NLog 的消息持久保存到数据库中。

也许你可以试试这个(仅适用于 NHibernate > 5.1.0):

NHibernateLogger.SetLoggersFactory(new NHibernate.Logging.NLog.NLogLoggerFactory());

并像这样实现 NLogLoggerFactory:

using NHibernate;
using NLog;
using System;
using System.Collections.Generic;

namespace NHibernate.Logging.NLog
{

    public class NLogLoggerFactory : INHibernateLoggerFactory
    {
        private readonly LogFactory _factory;

        public NLogLoggerFactory(LogFactory logFactory = null)
        {
            _factory = logFactory ?? LogManager.LogFactory;
        }

        public INHibernateLogger LoggerFor(string keyName)
        {
            return new NLogLogger(_factory.GetLogger(keyName));
        }

        public INHibernateLogger LoggerFor(Type type)
        {
            return new NLogLogger(_factory.GetLogger(type.ToString()));
        }
    }

    class NLogLogger : INHibernateLogger
    {
        private readonly ILogger _logger;

        private readonly Dictionary<NHibernateLogLevel, LogLevel> LevelMapping = new Dictionary<NHibernateLogLevel, LogLevel>() {
            { NHibernateLogLevel.Trace, LogLevel.Trace },
            { NHibernateLogLevel.Debug, LogLevel.Debug },
            { NHibernateLogLevel.Info, LogLevel.Info },
            { NHibernateLogLevel.Warn, LogLevel.Warn },
            { NHibernateLogLevel.Error, LogLevel.Error },
            { NHibernateLogLevel.Fatal, LogLevel.Fatal },
            { NHibernateLogLevel.None, LogLevel.Off },
        };

        public NLogLogger(NLog.ILogger logger)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        public bool IsEnabled(NHibernateLogLevel logLevel)
        {
            return _logger.IsEnabled(LevelMapping[logLevel]);
        }

        public void Log(NHibernateLogLevel logLevel, NHibernateLogValues state, Exception exception)
        {
            _logger.Log(LevelMapping[logLevel], exception, state.Format, state.Args);
        }
    }
}

几个月后 (!),我终于厌倦了为每个项目滚动我自己的微型库,并决定改为编写一个 public 库:RBC.NHibernate.NLog.