C# 如何将所有nlog文件目标指向其他临时路径?
假设我有两个记录器C# 如何将所有nlog文件目标指向其他临时路径?,c#,nlog,C#,Nlog,假设我有两个记录器A,B,它们写入文件目标A,B,E,如下所示: 现在我需要在程序运行时的一段时间内,不仅要使用${basepath},还要使用${InterimPath}。 时间窗口过后,它应该只继续写入${basepath}。 如何做到这一点 目前我能想到的唯一复杂的解决方案是以编程方式 迭代所有文件目标,并基于这些文件目标添加新目标,这些文件目标具有指向新路径的已更改名称、文件名和ArchiveFileName属性 迭代所有规则并添加新规则,并将writeTo更新为新的目标名称 在以后
A,B
,它们写入文件目标A,B,E
,如下所示:
现在我需要在程序运行时的一段时间内,不仅要使用${basepath}
,还要使用${InterimPath}
。
时间窗口过后,它应该只继续写入${basepath}
。
如何做到这一点
目前我能想到的唯一复杂的解决方案是以编程方式
更新:在时间窗口期间,两个路径(
$basepath
和$interimpath
)都应用于日志记录。在时间窗口之后,只应使用$basepath。有多种方法可以使其正常工作。我认为你的解决方案会奏效。我个人会选择以下解决方案之一:
GDC方法
这是一个非常简单的解决方案。使用全局诊断上下文并在需要时更改值。因此,无需在配置中进行迭代
将项目设置为初始值:
GlobalDiagnosticsContext.Set("myPath", basePath1);
如果需要,例如在计时器上或单击按钮时,更改基本路径
GlobalDiagnosticsContext.Set("myPath", basePath2);
在配置中:fileName=“${gdc:myPath}\E.log”
看
自定义布局渲染器方法
更自动化的是,创建一个自定义布局渲染器,根据时间返回不同的路径
寄存器(在main
或app\u start
中)
请参见更新的答案 单个FileTarget不可能将单个LogEvent转换为位于不同位置的两个文件写入。我建议你加倍:
<?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>
您可以像这样再次禁用2号目标(例如,当定时器触发时):
旧答案
您可以这样做:
${gdc:InterimPath:whenEmpty=${basepath}}
然后让定时器在超时后清除GDC中的InterimPath变量
GlobalDiagnosticsContext.Set("InterimPath", mySpecialPath);
另请参见:我的问题不是$interimpath或$basepath的情况,而是在时间窗口期间必须使用这两个路径进行日志记录,并且在持续时间结束后,仅使用$basepath。我在问题中添加了一个更新以使其更清楚。
GlobalDiagnosticsContext.Set("InterimPath", "");
LogManager.ReconfigExistingLoggers();
${gdc:InterimPath:whenEmpty=${basepath}}
GlobalDiagnosticsContext.Set("InterimPath", mySpecialPath);