【问题标题】:NLOG: how to use variable to specify targetNLOG:如何使用变量来指定目标
【发布时间】:2021-01-09 01:29:15
【问题描述】:

是否可以使用变量来指定特定的目标?

我想根据运行应用程序的环境在数据库和文件记录之间切换。

但这似乎不起作用:

<logger name="MyLogger" minlevel="Warn" writeTo="${var:myTargetName}" />

在我的应用程序启动中(第一行出现错误):

var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); 
var config = LoadConfiguration();
NLog.LogManager.Configuration.Variables["myTargetName"] = config.GetSection("LogTargets:TargetName").Value;   
NLog.LogManager.KeepVariablesOnReload = true;
NLog.LogManager.Configuration.Reload();

在应用程序启动时会抛出以下异常:

"Target ${var:myTargetName} not found."

我猜在解析配置文件时变量不可用。 如何设置变量以便 NLOG 在解析配置文件时使用它们? 是否可以使用变量来设置属性值? 还是 NLOG 不支持这个?

注意:我在 NLOG 配置中确实有另一个变量可以工作

<target xsi:type="Database" name="databaseTarget">
  <connectionString>${var:connectionString}</connectionString>
  ...........
</target>

我猜记录器在启动时会检查一次,并在发生日志事件时评估实际目标。

更新:让它在配置文件中没有变量的情况下工作。 我不得不从配置中删除记录器并通过代码创建它

var myCustomTarget = NLog.LogManager.Configuration.FindTargetByName(config.GetSection("LogTargets:TargetName").Value);
NLog.LogManager.Configuration.AddRuleForAllLevels(myCustomTarget , "MyLogger", true);

【问题讨论】:

标签: c# nlog


【解决方案1】:

一种方法是根据环境使用不同的 Web.config 文件,然后您将更改连接字符串。这就是我正在使用的方法。

一旦应用程序启动,NLOG 也会被初始化,因此您无法更改 NLOG.config 中写入的内容

【讨论】:

    【解决方案2】:

    通过 NLog.LogManager.Configuration.Variables 设置变量不适用于 nlog.config 文件中的所有属性。我不知道为什么,但这是一个已知问题,不幸的是它是如何工作的。但是有一个简单的解决方法,这里有一个例子,我是如何为目标的属性 connectionString 解决这个问题的。

    <target xsi:type="Database" name="tDatabase"
                dbProvider="Microsoft.Data.Sqlite.SqliteConnection, Microsoft.Data.Sqlite"
                connectionString="Data Source =.\${environment:DATABASE_FILE_NAME};"
                commandText="INSERT INTO ...">
          <parameter name="@MachineName" layout="${machinename}" />
          ...
    </target>
    

    您可以像这样在代码中简单地设置环境变量

    Environment.SetEnvironmentVariable("DATABASE_FILE_NAME", "foo.db");
    

    所以你只需使用 ${environment:DATABASE_FILE_NAME}

    Environment.SetEnvironmentVariable("DATABASE_FILE_NAME", "foo.db");
    

    而不是 ${var:DATABASE_FILE_NAME}

    NLog.LogManager.Configuration.Variables["DATABASE_FILE_NAME"] = "foo.db";
    

    【讨论】:

      【解决方案3】:

      NLog 4.6.7 可以更轻松地在运行时更新日志规则,如下所示:

      <nlog>
          <variable name="fileMinLevel" value="Off" />
          <variable name="databaseMinLevel" value="Off" />
          <rules>
            <logger minLevel="${var:fileMinLevel}" writeTo="fileTarget" />
            <logger minLevel="${var:databaseMinLevel}" writeTo="databaseTarget" />
          </rules>
      </nlog>
      

      那么你可以这样做:

      if (IsDevelopment())
             LogManager.Configuration.Variables["fileMinLevel"] = "Debug";
      else
             LogManager.Configuration.Variables["databaseMinLevel"] = "Debug";
      LogManager.ReconfigExistingLoggers();
      

      另请参阅:https://github.com/NLog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        相关资源
        最近更新 更多