Reputation: 81
I am writing a NLog file for an application. One of the requirements needed is that the user should be able to select the file size and the log level. The log level can be selected from a drop down menu. I was thinking that I can have a place holder for file size and log level. How can I go about doing this? Currently, I've done this:
<target name="logfile" xsi:type="File" FileName=".\logs\${shortdate}.log"
archiveFileName=".\logs\archive\${shortdate}.log"
maxArchiveFiles="60" archiveEvery="Day" archiveAboveSize="###MaxSize###"
layout="${longdate}|${level:uppercase=true}|${callsite}|${message}|${exception:format=toString}"/>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
I have two questions regarding this:
target
for each log level?Upvotes: 2
Views: 2298
Reputation: 19867
Semi Dynamic Routing Rules
NLog 4.6.7 makes it easy to change the LogLevel on-the-fly:
<nlog>
<variable name="myLevel" value="Trace" />
<rules>
<logger name="*" minlevel="${var:myLevel}" writeTo="logfile" />
</rules>
</nlog>
And then change it from runtime like this:
LogManager.Configuration.Variables["myLevel"] = "Debug";
LogManager.ReconfigExistingLoggers();
https://github.com/NLog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules
Rewrite and reload NLog.config
But it sounds like you should just perform a search and replace in the NLog.config
-file, and then perform an explicit reload:
<nlog>
<variable name="myLevel" value="Trace" />
<variable name="mySize" value="42" />
<targets>
<target name="logfile" xsi:type="File"
fileName=".\logs\${shortdate}.log"
archiveAboveSize="${mySize}" />
</targets>
<rules>
<logger name="*" minlevel="${var:myLevel}" writeTo="logfile" />
</rules>
</nlog>
After the file-rewrite/update (that changes the two variables) then explicit reload is done like this:
NLog.LogManager.Configuration = NLog.LogManager.Configuration?.Reload();
Alternative to explicit reload would be to use <nlog autoReload="true">
(Then NLog will detect changes to NLog.config
-file and reload automatically).
Rewrite and reload NLog.user.config
If you feel excited and like advanced stuff, then you could also make use of include-files, and have a default NLog.config
that includes NLog.user.config
:
<nlog autoreload="true">
<variable name="myLevel" value="Trace" />
<variable name="mySize" value="42" />
<include file="NLog.user.config" ignoreErrors="true" /> <!-- Can override variables -->
<targets>
<target name="logfile" xsi:type="File"
fileName=".\logs\${shortdate}.log"
archiveAboveSize="${mySize}" />
</targets>
<rules>
<logger name="*" minlevel="${var:myLevel}" writeTo="logfile" />
</rules>
</nlog>
See also: https://github.com/NLog/NLog/wiki/XML-config-include-Example
Upvotes: 3
Reputation: 16104
Building upon Combine nlog.config and config from code
Please note that combining the config file (nlog.config) and changing it in code, the reload of nlog.config could undo your changes. If you combine both, then reapply the changes on the reload event. E.g.
// On start of your program
UpdateConfig();
LogManager.ConfigurationReloaded += (sender, e) =>
{
//Re apply if config reloaded
UpdateConfig();
};
Where UpdateConfig is
public void UpdateConfig()
{
var configuration = LogManager.Configuration;
var fileTarget = configuration.FindTargetByName<FileTarget>("myTargetName");
fileTarget.FileName = "${basedir}/file.log";
LogManager.Configuration = configuration; //apply
}
and then, I'd tweak this to
public void UpdateConfig()
{
var configuration = LogManager.Configuration;
// Get User-Defined LogLevel and FileSize from App Settings
// Set NLog LogLevel and FileSize
LogManager.Configuration = configuration; //apply
}
while in the handler for the Log-Config-Dialog, I'd write Level and FileSize to App Settings, then call UpdateConfig
.
Make sure to either ship with defaults set for those app settings or handle the settings not been set, yet.
Upvotes: 3