使用 DI 并使用 appsettings.json 将 Nlog 日志记录到数据库 .NET 5.0

Posted

技术标签:

【中文标题】使用 DI 并使用 appsettings.json 将 Nlog 日志记录到数据库 .NET 5.0【英文标题】:Nlog log to database .NET 5.0 with DI and using appsettings.json 【发布时间】:2021-12-26 17:23:12 【问题描述】:

我一直在尝试让 Nlog 将日志记录发送到数据库,但我发现的示例都返回了内部 nlog 错误。我在带有 .NET 5.0 的控制台应用程序中使用依赖注入...:

Info Adding target ConsoleTarget(Name=console)
Warn Error has been raised. Exception: NLog.NLogConfigurationException: Failed to create Target of type: Database
 ---> System.ArgumentException: Target cannot be found: 'Database'. Extension NLog.Database not included?
   at NLog.Config.Factory`2.CreateInstance(String itemName)
   at NLog.Config.LoggingConfigurationParser.FactoryCreateInstance[T](String classType, INamedItemFactory`2 factory)
   --- End of inner exception stack trace ---
Warn Error has been raised. Exception: NLog.NLogConfigurationException: Target 'dbTarget' not found for logging rule: *.

在我的 json 中,我有以下内容:

  "NLog": 
    "internalLogLevel": "info",
    "internalLogFile": "$basedir/logs/internal-nlog.txt",
    "extensions": 
      "NLog.Extensions.Logging": 
        "assembly": "NLog.Web.AspNetCore"
      
    ,
    "targets": 
      "database": 
        "type": "Database",
        "name": "dbTarget",
        "dbProvider": "Microsoft.Data.SqlClient.SqlConnection,Microsoft.Data.SqlClient",
        "connectionString": "myconnectionstring",
        "commandText": "INSERT INTO dbo.Logs (Level,CallSite,Type,Message,StackTrace,InnerException,AdditionalInfo) values (@level, @callSite, @type, @message, @stackTrace, @innerException, @additionalInfo)",
        "parameters": [
          
            "lots of parameters follow"
          
        ]

      
    ,
    "rules": [
      
        "logger": "*",
        "minLevel": "Debug",
        "writeTo": "dbTarget"
      
    ]

这是在我的 Main() 中:

        static void Main(string[] args)
        
            ApplicationSettings applicationSettings = new ApplicationSettings();

            var settings = applicationSettings.GetConfiguration();

            var host = Host.CreateDefaultBuilder()
            .ConfigureServices((context, services) =>
            
                services.AddSingleton<IApplicationSettings, ApplicationSettings>();
                services.AddSingleton<IApplication, Application>();
                services.AddSingleton<ITeamMemberProcessor, TeamMemberProcessor>();
                services.AddLogging(loggingBuilder =>
                
                    loggingBuilder.ClearProviders();
                    loggingBuilder.AddNLog();
                );
            )
            .Build();
            

            var svc = ActivatorUtilities.CreateInstance<Application>(host.Services);
            svc.Run();
        

我错过了什么吗?写入文件和写入控制台工作正常。另外,据我了解,不应再使用 nlog.config 了。我们应该使用 appsettings.json 吗?

谢谢!

戴夫

【问题讨论】:

【参考方案1】:

我猜你正在使用 NLog 5.0,其中 NLog DatabaseTarget 一直是 extracted into a seperate nuget-package。

猜猜错误信息想说什么:

Exception: NLog.NLogConfigurationException: Failed to create Target of type: Database
 ---> System.ArgumentException: Target cannot be found: 'Database'. Extension NLog.Database not included?

它希望您从 nuget 安装扩展程序 NLog.Database,并将其添加到 NLog 配置中。像这样的:

"NLog": 
    "internalLogLevel": "info",
    "internalLogFile": "$basedir/logs/internal-nlog.txt",
    "extensions": [
       "assembly": "NLog.Database" ,
       "assembly": "NLog.Web.AspNetCore" 
    ],
    "targets": 
        "database": 
        "type": "Database",
        "name": "dbTarget",
        "dbProvider": "Microsoft.Data.SqlClient.SqlConnection,Microsoft.Data.SqlClient",
        "connectionString": "myconnectionstring",
        "commandText": "INSERT INTO dbo.Logs (Level,CallSite,Type,Message,StackTrace,InnerException,AdditionalInfo) values (@level, @callSite, @type, @message, @stackTrace, @innerException, @additionalInfo)",
        "parameters": [
            
            "lots of parameters follow"
            
        ]

        
    ,
    "rules": [
        
        "logger": "*",
        "minLevel": "Debug",
        "writeTo": "dbTarget"
        
    ]

【讨论】:

这很奇怪,我认为它必须是旧的.. 它没有显示在搜索 Nuget 时,当我通过命令行安装它时,我收到一个错误,它会降级我有一个更新的版本:安装包:NU1605:检测到的包降级:NLog 从 5.0.0-preview.3 到 4.7.12。直接从项目中引用包来选择不同的版本。 @DaveM 不确定我是否理解 NLog.Database 取决于 NLog 5.0.0-preview.3。也许您的解决方案中的其他项目取决于 NLog 4.7.12?【参考方案2】:

所以,我能够让它“工作”,尽管没有 DI.. 我仍然想弄清楚。看起来好像我的 ApplicationSettings 中缺少两行:

            LogManager.Configuration = new NLogLoggingConfiguration(_configuration.GetSection("NLog"));
            var logger = NLogBuilder.ConfigureNLog(LogManager.Configuration).GetCurrentClassLogger();

然后在我的“应用程序”类中,我删除了 Logging 注入,并将其添加到我的“运行”方法的顶部:

var _logger = LogManager.Setup().LoadConfigurationFromSection(_configuration).GetCurrentClassLogger();

然后它工作了.. 再次,我猜我错过了一些东西,所以我可以使用依赖注入?但我不确定是什么..

感谢您的回复,感谢您抽出宝贵时间!

戴夫

【讨论】:

听起来很奇怪,这取决于您如何加载 NLog-config 是否收到异常 Failed to create Target of type: Database。但很高兴你找到了方法。请注意 NLog.Web.AspNetCore 版本。 5.0默认会自动从appsettings.json加载NLog-config(不再需要NLogBuilderLoadConfigurationFromSection

以上是关于使用 DI 并使用 appsettings.json 将 Nlog 日志记录到数据库 .NET 5.0的主要内容,如果未能解决你的问题,请参考以下文章

DI 原理解析 并实现一个简易版 DI 容器

使用jquery设置di​​v标签的值

Azure Functions 中的 DI

汇编SI DI 的用法

SwiftUI + MVVM + DI

Spring01-控制反转(IOC)与依赖注入(DI)