Dynamically Set NLog Levels in Code

Dale Bingham
3 min readMar 30, 2022

Do you want to set NLog levels dynamically for running your application with different logging levels? We did. And we had to read a bunch of various posts and examples to figure it out correctly.

TLDR; In the end, we added a variable in the nlog.config and read that in on program startup to set it dynamically. Here is how we did it below as an example to possibly help you. And to remind us (me) later how to do it!

NLog variable to set the log level on startup in .NET / .NET Core

NLog Configuration with Variables

A little background here. We have a few containerized application components that we are working on for OpenRMF Professional. We wanted to allow customers to make logs more or less verbose to help us help them during remote disconnected network troubleshooting. By default we report Critical/Fatal, Error and Warning. However, with this setup discussed here we can allow them to alter that level for various reasons.

We have an environment variable called “LOGLEVEL” that we read in on the Program.cs Main() routine and read in the nlog.config file, set the level, and then engage the rest of the application. Based on the various LogInformation(), LogDebug(), and other logging routines the data logged can be throttled to what you need. On our end you will see we also use ELK for logging. So we have a local “Logstash” configuration as well.

The block below and pictured above shows the {$var:logLevel} level set in the nlog.config file we read in at runtime.

<!-- rules to map from logger name to target -->
<rules>
<logger name="Microsoft.*" maxLevel="${var:logLevel}" final="true" />
<logger name="*" minlevel="${var:logLevel}" writeTo="Console" />
<logger name="*" minlevel="${var:logLevel}" writeTo="Logstash" />
</rules>

Setting Your NLog Level at Startup

We use the NuGet packages below to reference in our API and NATS message client code. The NLog.Web is a little different setup than regular NLog reading in the nlog.config file. They are pretty similar though. Check the NLog website for configuration information. The NuGet packages are the same, minus the Web.AspNetCore one.

<PackageReference Include="NLog" Version="4.7.13" />
<PackageReference Include="NLog.StructuredLogging.Json" Version="4.0.0" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />

To set the actual level logged, in our environment area we specify the “LOGLEVEL” similar to below. Depending on your coding environment and your runtime environment the variable may be set differently. Our example is similar to the below code to make it easy for customers to set this and understand it. We use containerized applications so the YML file for them would have an area for this for that component. And we walk them through setting that and restarting that component.

"env" : {
"LOGLEVEL" : "3"
},

The Program.cs Main() function code to read in the log file is just below. Your setup and way to set the level may differ. However, from the code block below you should be able to see how YOU can do this in YOUR code as well. If there is no available environment variable, then we default to WARN level. Otherwise we set it based on the level passed in. And we default to the WARN level. The NLog.LogManager.Configuration.Variables[“logLevel”] corresponds to the nlog.config {$var:logLevel}.

var logger = 
NLog.Web.NLogBuilder.ConfigureNLog("nlog.config")
.GetCurrentClassLogger();
if (string.IsNullOrEmpty(
Environment.GetEnvironmentVariable("LOGLEVEL")))
NLog.LogManager.Configuration.Variables["logLevel"]
= "Warn";
else {
switch (Environment.GetEnvironmentVariable("LOGLEVEL"))
{
case "5":
NLog.LogManager.Configuration.Variables["logLevel"] = "Critical";
break;
case "4":
NLog.LogManager.Configuration.Variables["logLevel"] = "Error";
break;
case "3":
NLog.LogManager.Configuration.Variables["logLevel"] = "Warn";
break;
case "2":
NLog.LogManager.Configuration.Variables["logLevel"] = "Info";
break;
case "1":
NLog.LogManager.Configuration.Variables["logLevel"] = "Debug";
break;
case "0":
NLog.LogManager.Configuration.Variables["logLevel"] = "Trace";
break;
default:
NLog.LogManager.Configuration.Variables["logLevel"] = "Warn";
break;
}
}
// reset based on the variable passed in
NLog.LogManager.ReconfigExistingLoggers();

Test Your NLog Configuration

Now that you have your environment variable set, your nlog.config set, and your Program.cs Main() code done you can test it and tweak your code and documentation accordingly. If you are using VS Code like we do, you may need to copy your nlog.config into your bin/Debug/net6.0/ directory possibly to make your code read in the file properly in debug sessions. Once you are set, debug or run and try different levels.

You will need various LogInformation(), LogDebug(), LogCritical(), LogWarning(), LogError() or LogTrace() logger calls within your code to test the levels. And to make sure you have the logging in the appropriate areas to help you collect information to track your application runtime results.

Happy Coding!

--

--

Dale Bingham

CEO of Soteria Software. Developer on OpenRMF. Software Geek by trade. Father of three daughters. Husband. Love new tech where it fits. Follow at @soteriasoft