Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change basedir in NLog Targets in runtime programmatically

Tags:

c#

nlog

I have Windows Forms app NET 4.5 (VS 2013) using NLog.

I have targets:

<target name="asyncFileLog" xsi:type="AsyncWrapper">
  <target name="logfileTrace" xsi:type="File" fileName="${basedir}/logs/${shortdate}Trace.log" layout="${longdate} ${message}" lineEnding="Default"/>
</target>

<target name="asyncFileError" xsi:type="AsyncWrapper">
  <target name="logfileError" xsi:type="File" fileName="${basedir}/logs/${shortdate}Error.log" layout="${longdate} ${message} ${exception:format=tostring}"  lineEnding="Default"/>
</target>

LogManager.Configuration.AllTargets.ToList(); returns 4 items, not 2 items.

I want change the path ${basedir}/logs in runtime, programmatically

I try this:

var rutaLogs = ConfigurationManager.AppSettings["RutaLog"];
if (!Directory.Exists(rutaLogs)) return;

var list = LogManager.Configuration.AllTargets.ToList();
foreach (var target in list)
{
    FileTarget fileTarget = null;
    var wrapperTarget = target as WrapperTargetBase;

    // Unwrap the target if necessary.
    if (wrapperTarget == null)
    {
        fileTarget = target as FileTarget;
    }
    else
    {
        fileTarget = wrapperTarget.WrappedTarget as FileTarget;
        continue;
    }

    var value = fileTarget.FileName.ToString();
    value = value.Replace("${basedir}/logs/", rutaLogs);
    fileTarget.FileName = value;
}

Not generates anything. I try using LogManager.ReconfigExistingLoggers(); too, but not working.

Any suggestions?

like image 515
Kiquenet Avatar asked Mar 02 '17 08:03

Kiquenet


1 Answers

It's easier to use variables in this case. (${var:...})

For this example:

<variable name="basedir" value="${basedir}" />    <!-- default, optional -->

<targets>
   <target name="asyncFileLog" xsi:type="AsyncWrapper">
     <target name="logfileTrace" xsi:type="File" 
             fileName="${var:basedir}/logs/${shortdate}Trace.log" 
             layout="${longdate} ${message}" lineEnding="Default"/> 
   </target>
   ...

Changing the variable in C#

// create or edit
LogManager.Configuration.Variables["basedir"] = "d:/mybasedir";

No need for LogManager.ReconfigExistingLoggers(); or looping over all the targets!

See also the ${var} documentation

Update: in this case your are reading from .config files, this could be done with only NLog configuration (no C# needed!)

Install NLog.Extended and use ${appsetting:name=..}

e.g.

fileName="${var:basedir}/logs/${appsetting:name=RutaLog}Trace.log" 

See also the ${appsetting} documentation

like image 56
Julian Avatar answered Oct 12 '22 00:10

Julian