Assume i have two loggers A, B
which write to file targets A, B, E
like so:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets async="true">
<target name="A" xsi:type="File" fileName="${basepath}\A.log" archiveFileName="${basepath}\A.{##}.log" />
<target name="B" xsi:type="File" fileName="${basepath}\B.log" archiveFileName="${basepath}\B{##}.log" />
<target name="E" xsi:type="File" fileName="${basepath}\E.log" archiveFileName="${basepath}\E{##}.log" />
</targets>
<rules>
<logger name="A" minlevel="Debug" writeTo="A"/>
<logger name="B" minlevel="Debug" writeTo="B"/>
<logger name="*" minlevel="Error" writeTo="E"/>
</rules>
</nlog>
Now i have the requirement, for some time window during program runtime, to not only use ${basepath}
but also an ${InterimPath}
.
After the time window elapses, it should continue writing only to ${basepath}
.
How would one accomplish this?
The only complicated solution i can think of currently, is to programmatically
Update: Both Paths ($basepath
and $interimpath
) should be used for logging during the time window. After the time window only $basepath should be used.
Updated Answer
It is not possible for a single FileTarget to translate a single LogEvent into two file-writes at different locations. I suggest that you double-up:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variable name="InterimPath" value="${gdc:InterimPath}" />
<variable name="InterimPathOff" value="${gdc:InterimPath:whenEmpty=Off}" />
<targets async="true">
<target name="A1" xsi:type="File" fileName="${basepath}\A.log" archiveFileName="${basepath}\A.{##}.log" />
<target name="A2" xsi:type="File" fileName="${InterimPath}\A.log" archiveFileName="${interimpath}\A.{##}.log" />
<target name="B1" xsi:type="File" fileName="${basepath}\B.log" archiveFileName="${basepath}\B{##}.log" />
<target name="B2" xsi:type="File" fileName="${InterimPath}\B.log" archiveFileName="${interimpath}\B{##}.log" />
<target name="E1" xsi:type="File" fileName="${basepath}\E.log" archiveFileName="${basepath}\E{##}.log" />
<target name="E2" xsi:type="File" fileName="${InterimPath}\E.log" archiveFileName="${interimpath}\E{##}.log" />
</targets>
<rules>
<logger name="A" minlevel="Debug" writeTo="A1"/>
<logger name="A" minlevel="${whenEmpty:whenEmpty=${InterimPathOff}:inner=Debug" writeTo="A2"/>
<logger name="B" minlevel="Debug" writeTo="B1"/>
<logger name="B" minlevel="${whenEmpty:whenEmpty=${InterimPathOff}:inner=Debug" writeTo="B2"/>
<logger name="*" minlevel="Error" writeTo="E1"/>
<logger name="*" minlevel="${whenEmpty:whenEmpty=${InterimPathOff}:inner=Error" writeTo="E2"/>
</rules>
</nlog>
Then you can enable the no. 2 targets by doing this:
GlobalDiagnosticsContext.Set("InterimPath", mySpecialPath);
LogManager.ReconfigExistingLoggers();
And you can disable the no. 2 targets again like this (Ex. when timer fires):
GlobalDiagnosticsContext.Set("InterimPath", "");
LogManager.ReconfigExistingLoggers();
Old Answer
You could do this:
${gdc:InterimPath:whenEmpty=${basepath}}
Then just have timer to clear the InterimPath variable from the GDC after timeout
GlobalDiagnosticsContext.Set("InterimPath", mySpecialPath);
See also: https://github.com/nlog/nlog/wiki/Gdc-Layout-Renderer