Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update NLog target filename at runtime

Tags:

In my application, I work on several thousand of document a day. I'd like, in some cases some logs, one log by document. Then I'd like for a specific target change the output filename (and only the filename) at runtime.

Around the web I found how to create a target by programming me I'd like just update a the filename by programming. I tried the code below. The error I receive is "LayoutRender cannot be found 'logDirectory'.

Any idea ?

Thanks,

var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile"); target.FileName = "${logDirectory}/file2.txt";  LoggingConfiguration config = new LoggingConfiguration(); var asyncFileTarget = new AsyncTargetWrapper(target); config.AddTarget("logfile", asyncFileTarget);  LogManager.Configuration = config; 

The config file is :

  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">     <variable name="logDirectory" value="C:/MyLogs"/>     <targets>       <target name="logfile" xsi:type="File" layout="${date:format=dd/MM/yyyy HH\:mm\:ss.fff}|${level}|${stacktrace}|${message}" fileName="${logDirectory}/file.txt" />     </targets>      <rules>       <logger name="*" minlevel="Info" writeTo="logfile" />     </rules>       </nlog> 
like image 862
Kris-I Avatar asked Dec 24 '13 07:12

Kris-I


2 Answers

Try ReconfigExistingLoggers method:

var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile"); target.FileName = "${logDirectory}/file2.txt"; LogManager.ReconfigExistingLoggers(); 

As written in docs:

Loops through all loggers previously returned by GetLogger. and recalculates their target and filter list. Useful after modifying the configuration programmatically to ensure that all loggers have been properly configured.

EDIT:

Try use custom layout renderer: NLog config file to get configuration setting values from a web.config

like image 172
Tony Avatar answered Sep 23 '22 18:09

Tony


Tony's solution doesn't seem to work if you use NLog Async (<targets async="true">). I had to use the wrapper target to get my FileTarget, otherwise I get a lot of errors. I'm using NLog 2.1.

if (LogManager.Configuration != null && LogManager.Configuration.ConfiguredNamedTargets.Count != 0) {     Target target = LogManager.Configuration.FindTargetByName("yourFileName");     if (target == null)     {         throw new Exception("Could not find target named: " + "file");     }      FileTarget fileTarget = null;     WrapperTargetBase wrapperTarget = target as WrapperTargetBase;      // Unwrap the target if necessary.     if (wrapperTarget == null)     {         fileTarget = target as FileTarget;     }     else     {         fileTarget = wrapperTarget.WrappedTarget as FileTarget;     }      if (fileTarget == null)     {         throw new Exception("Could not get a FileTarget from " + target.GetType());     }      fileTarget.FileName = "SetFileNameHere";     LogManager.ReconfigExistingLoggers(); } 

This also doesn't change the config file, it just changes the runtime value. So I also manually edit the config file to my new value using the code below:

var nlogConfigFile = "NLog.config"; var xdoc = XDocument.Load(nlogConfigFile); var ns = xdoc.Root.GetDefaultNamespace(); var fTarget = xdoc.Descendants(ns + "target")          .FirstOrDefault(t => (string)t.Attribute("name") == "yourFileName"); fTarget.SetAttributeValue("fileName", "SetFileNameHere"); xdoc.Save(nlogConfigFile); 
like image 21
Baddack Avatar answered Sep 26 '22 18:09

Baddack