使用NLog.Web.AspNetCore进行NHibernate日志记录

问题描述

我几乎浪费了整整一天的时间,试图通过NLog.Web.AspNetCore为ASP.Net Core项目制作NHibernate日志消息-毫无用处。我能找到的唯一示例是隐藏的deep inside the NHibernate Git repository,但是它不适用于现代版本的Microsoft日志记录库。更不用说这是一个非常简单的解决方案,因为我必须复制/粘贴该文件夹中的两个辅助类,才能在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);
        }
    }
}