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

岁酱吖の 提交于 2019-12-08 03:29:48

问题


Using NLog v4.4.12, I have this in my App.config

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

And here is my Variables.xml file content

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

But I get an Exception when launching my app

Unknown log level: ${logLevel}

Am I doing something wrong or is it just impossible?

The goal of this is to eventually have an xml file per project that need to log things so each project can have his own minlevel and be able to change it at runtime via the edition of this xml.

Edit: Adding this code just before the Exception is thrown shows that my variable is there with the desired value.

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

回答1:


** Updated Answer **

NLog ver. 4.6 added support for using NLog-Config-Variables in minLevel. See https://github.com/NLog/NLog/pull/2709

NLog ver. 4.6.7 added support for adjusting minLevel at runtime, by modifying NLog-Config-Variables and calling ReconfigExistingLoggers(). See https://github.com/NLog/NLog/pull/3184

** Original Answer **

Unfortunately you can't use layout renderers (the ${...}) in the <logger> attributes like minLevel, level, etc

There are two options:

Use filters

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

Downsides:

  • less readable
  • hurt performance more compared to the minLevel attribute

Change the rules in code

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;



回答2:


I had my variables in a config file as part of a Service Fabric application, which would vary by environment, and wanted these to override the values in my Nlog.config file. As per the user above, I came up against the same problem with loglevel when I wished to set a minimum level for it. Rather than hardcoding the levels in the code, I created a variable to retrieve the value from my config file, along the lines of what the original user had done:

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

I set the variables that could be set, such as connection string etc. using the GlobalDiagnosticsContext, but obviously couldn't set the loglevel this way, due to its dislike of variables!

So instead, I did the following:

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

The 'SetloggingLevels' method expects values for Minlevel and MaxLevel of logging, hence my Config value was the min, and I hardcoded "Fatal" as the max since I was after a replication of 'minLevel' type logging, although obviously this too could have been set in my config file.



来源:https://stackoverflow.com/questions/47946734/is-there-a-way-to-set-the-minlevel-of-a-nlog-logger-via-a-variable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!