【问题标题】:How to Properly Pull NLog DB ConnectionString from appsettings.json如何从 appsettings.json 中正确提取 NLog DB ConnectionString
【发布时间】:2021-06-21 15:36:22
【问题描述】:

我有我的nlog.config 文件设置和一个数据库目标,并想从appsettings.json 读取连接字符串(对于任何感兴趣的人,appsettings 中的值实际上存储在 Azure KeyVault 中)。这样做的正确方法是什么?我有 ASP.NET core 3.1 应用程序。

nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<!--The first nLog section internal log file logs the NLog configuration issues, Don't remove this-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="debug"
      internalLogFile="c:\temp\foo.txt">


  <extensions>
    <add assembly="NLog.Extensions.Logging"/>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  
    <variable name="defaultLayout" value="${date} ${threadid} ${uppercase:${level}} ${logger} ${ndc} - ${message}${newline}" />
    <variable name="logDirectory" value="./logs/${shortdate}"/>
    <variable name="apiFileLogPath" value="c:\temp\api-nlog.txt"/>
    
    <!-- the targets to write to -->
    <targets>
        <target name="dbTarget"
                xsi:type="Database"
                commandText="..."
            connectionString="${configsetting:item=NLogConfiguration.ConnectionString}">
            <!--<connectionString></connectionString>-->
        </target>
        <!-- write to the void aka just remove -->
        <target xsi:type="Null" name="blackhole" />
    </targets>

    <!-- rules to map from logger name to target -->
    <rules>

        <!--Skip Microsoft logs and so log only own logs-->
        <!--<logger name="*" minlevel="Trace" writeTo="blackhole" final="true" />-->
        <logger name="*" minlevel="Debug" writeTo="dbTarget" />
    </rules>
</nlog>

appsettings.json 文件的相关部分:

{
  "NLogConfiguration": {
    "ConnectionString": "..."
  }
}

我的代码中有一个断点来检查数据库目标,但未设置 connectionString 值。它保留为${configsetting:item=NLogConfiguration.ConnectionString}

我在启动时没有任何 NLog 代码。我有一个围绕 NLog 的包装类,并且正在以这种方式对其进行初始化。该类如下所示:

DBLogManager

using System;
using System.Configuration;
using System.Globalization;
using System.Web;
using NLog;
using System.Xml;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.Extensions.Configuration;

namespace DBLog.DBLogManager
{

    public class DBLogManager : IDBLogManager
    {
        static ILogger InitializeDBLogManager()
        {
            XmlDocument nLogConfig = new XmlDocument();
            var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nlog.config");

            NLog.LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(path);
            
            return LogManager.GetLogger("AppLogger");

        }
        private static readonly ILogger Logger = InitializeDBLogManager();
    }
}

【问题讨论】:

  • 您的配置 internalLogFile="c:\temp\foo.txt&gt; 中存在 XML 错误。这是复制粘贴错误吗? (缺少报价)
  • @Julian 是的复制粘贴错误。谢谢。我更新了。
  • @Bmoe 也许还包括初始化主机的代码,并实际加载应用程序设置,因为 NLog 需要一点帮助才能从主机访问应用程序设置。

标签: c# nlog asp.net-core-3.1


【解决方案1】:

我会将DBLogManager 更改为:

namespace DBLog.DBLogManager
{
    public class DBLogManager : IDBLogManager
    {
        // NLog will automatically load NLog.config from AppDomain.BaseDirectory
        private static readonly NLog.Logger Logger = NLog.LogManager.GetLogger("AppLogger");
    }
}

然后像这样添加UseNLog()

public static IHostBuilder CreateHostBuilder(string[] args) =>
   Host.CreateDefaultBuilder(args)
       .UseNLog();

如果您想在 IHostBuilder 之前创建 NLog Logger,请执行此操作(而不是 NLogBuilder.ConfigureNLog):

var logger = LogManager.Setup()
                       .LoadConfigurationFromAppSettings()
                       .GetCurrentClassLogger();

【讨论】:

  • 朱利安的回答实际上有所帮助,而且早于你的回答。我只需要把碎片拼凑起来。谢谢。
  • @bmoe 是的,没问题。我只是想强调DBLogManager 中包含的代码是不必要的。
  • 我想这个答案更好,所以请随意标记为答案:)
【解决方案2】:

对于${configsetting},您至少需要包NLog.Extensions.Logging 或依赖包之一,例如NLog.Web.AspNetCore 或NLog.Extensions.Hosting。

通常你会在IHostBuilder 上使用.UseNLog(),参见NLog - Getting started with ASP.NET Core 3

使用${configsetting}手动注册微软扩展IConfiguration

IConfigurationRoot config = new ConfigurationBuilder()
    .AddJsonFile(path: "AppSettings.json").Build();
NLog.Extensions.Logging.ConfigSettingLayoutRenderer.DefaultConfiguration = config;

NLog - ConfigSetting Layout Renderer

【讨论】:

  • 是否需要AddJsonFile 行?我没有,但我的应用程序仍然能够读取appsettings.json 文件。
  • 我没有投反对票,但我认为这是因为您只是重新使用了现有的文档,显然人们一开始并不理解。我想你会提供一个工作样本的期望。您发布的代码行,除非我之前使用过 Startup 代码,否则我个人不会知道它们的去向。
  • 您需要分配NLog.Extensions.Logging.ConfigSettingLayoutRenderer.DefaultConfiguration。您还可以解析配置,具体取决于您的其余代码
  • @Julian 我们可以把这段代码放在program.cs?
  • @RahulHendawe 在Main?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 2017-04-14
  • 2018-01-29
  • 2016-09-29
  • 2018-01-01
相关资源
最近更新 更多