有没有办法通过变量设置 NLog 记录器的最小级别?

Is there a way to set the minlevel of a NLog logger via a variable?

使用 NLog v4.4.12,我的 App.config

<nlog>
    <include file="..\Common\Logs\Variables.xml" />
    <rules>
        <logger name="*" minlevel="${logLevel}" writeTo="LogFile, Wcf"/>
    </rules>
</nlog>

这是我的 Variables.xml 文件内容

<?xml version="1.0" encoding="utf-8"?>
<nlog autoReload="true">
  <variable name="logLevel" value="Fatal" />
</nlog>

但是我在启动我的应用程序时遇到异常

Unknown log level: ${logLevel}

我做错了什么还是根本不可能?

这样做的目标是最终让每个项目都有一个 xml 文件来记录事情,这样每个项目都可以有自己的最小级别,并且能够在运行时通过这个 xml.

编辑: 在抛出异常之前添加此代码表明我的变量已具有所需的值。

var nl = NLog.LogManager.Configuration;
if (nl != null)
{
    if (nl.Variables.ContainsKey("logLevel"))
    {
            Console.WriteLine(nl.Variables["logLevel"]);
    }
}

** 更新的答案 **

NLog 版本。 4.6 添加了对在 minLevel 中使用 NLog-Config-Variables 的支持。参见 https://github.com/NLog/NLog/pull/2709

NLog 版本。 4.6.7 通过修改 NLog-Config-Variables 并调用 ReconfigExistingLoggers() 添加了对在运行时调整 minLevel 的支持。参见 https://github.com/NLog/NLog/pull/3184

** 原始答案 **

遗憾的是,您不能在 <logger> 属性(如 minLevel、level 等)中使用布局渲染器(${...}

有两种选择:

使用过滤器

 <logger name="*"  writeTo="LogFile, Wcf">
      <filters>
          <when condition="(level &lt; ${logLevel})" action="Ignore"/>
      </filters>      
 </logger>

缺点:

  • 可读性较差
  • 与 minLevel 属性相比,对性能的影响更大

更改代码中的规则

var rule = config.LoggingRules[0];
// disable old levels, enable new
rule.DisableLoggingForLevel(LogLevel.Debug);
rule.DisableLoggingForLevel(LogLevel.Trace);
rule.EnableLoggingForLevels(LogLevel.Info, LogLevel.Fatal);

//apply config
LogManager.Configuration = config;

我在配置文件中有我的变量作为 Service Fabric 应用程序的一部分,它会因环境而异,并且希望这些变量覆盖我的 Nlog.config 文件中的值。 根据上面的用户,当我希望为它设置最低级别时,我遇到了与日志级别相同的问题。我没有在代码中对级别进行硬编码,而是创建了一个变量来从我的配置文件中检索值,按照原始用户所做的行:

var config = context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
ILoggerFactory logger = new LoggerFactory().AddNLog();
var nlogConfigSection = config.Settings.Sections["MyService_NlogSettings"];

我使用GlobalDiagnosticsContext设置了可以设置的变量,比如连接字符串等,但是显然不能这样设置loglevel,因为它不喜欢变量!

因此,我执行了以下操作:

LogManager.Configuration.LoggingRules[0].SetLoggingLevels((NLog.LogLevel.FromString(nlogConfigSection.Parameters["AzureNLogLevel"].Value)),
                       NLog.LogLevel.FromString("Fatal"));  

'SetloggingLevels' 方法需要日志记录的 Minlevel 和 MaxLevel 值,因此我的 Config 值为最小值,并且我将 "Fatal" 硬编码为最大值,因为我是在复制 'minLevel' 类型日志记录,虽然显然这也可以在我的配置文件中设置。