I'm trying to log to a file using NLog based on a globally-set log level. I'm unsure if this is possible from everything I can dig up.
Essentially, I want to have a global setting in my appconfig.json
that has the log level. Default would be Debug
, but Trace
would be another option. If I select Debug
, I want to log everything from Debug
up to Fatal
in a file called log-debug.txt
. This seems pretty reasonable; it's the base tutorial case from what I can tell, and I've made that work.
Here's the other thing, though: if I set the global log level to Trace
, I want everything from Trace
on up to log to log-trace.txt
. My initial thought was to add a new config rule, so I added the second one in the rules
collection, but from everything I've read that would end up with the debug messages in one file and the trace messages in another.
The purpose of this is extreme-case debugging (i.e., user doesn't have any idea how they got to that state, so flip the setting from "Debug" to "Trace", play with it again, and when you hit the bug send me the log-trace.txt), so splitting the debug and trace messages into different files would defeat the purpose.
How would I go about doing this?
This is a WPF app, so I'm setting the global level by using this in app.xaml.cs
:
serviceCollection.AddLogging(builder =>
{
builder.ClearProviders();
// Haven't written the code to pull it from the config file yet, but this is how
// I would set it.
builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.AddNLog();
});
appconfig.json
{
"settings": {
"logLevel": "Debug"
},
"NLog": {
"internalLogLevel": "Info",
"autoReload": true,
"targets": {
"logfile-debug": {
"type": "File",
"fileName": "log-debug.txt",
"layout": "${longdate}|${level}|${message}|${exception:format=tostring}"
},
"logfile-trace": {
"type": "File",
"fileName": "log-trace.txt",
"layout": "${longdate}|${level}|${message}|${exception:format=tostring}",
},
"logconsole": {
"type": "Debugger",
"layout": "${longdate}|${level}|${message}|${exception:format=tostring}"
}
},
"rules": [
{
"logger": "*",
"minLevel": "Debug",
"writeTo": "logfile-debug,logconsole"
},
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "logfile-trace,logconsole"
}
]
}
}
CodePudding user response:
You can do this:
void EnableGlobalTrace(bool enable)
{
NLog.GlobalDiagnosticsContext.Set("GlobalTraceLevel", enable ? "Trace" : "Off");
NLog.LogManager.ReconfigureExistingLoggers();
}
And have the rules like this:
"rules": [
{
"logger": "*",
"minLevel": "Debug",
"writeTo": "logfile-debug,logconsole"
},
{
"logger": "*",
"minLevel": "${gdc:GlobalTraceLevel:whenEmpty=Off}",
"writeTo": "logfile-trace"
}
]
See also: https://github.com/NLog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules