Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将所有nlog文件目标指向其他临时路径?_C#_Nlog - Fatal编程技术网

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}
。 如何做到这一点

目前我能想到的唯一复杂的解决方案是以编程方式

  • 迭代所有文件目标,并基于这些文件目标添加新目标,这些文件目标具有指向新路径的已更改名称、文件名和ArchiveFileName属性
  • 迭代所有规则并添加新规则,并将writeTo更新为新的目标名称
  • 在以后的某个时间点删除这些目标和规则

  • 更新:在时间窗口期间,两个路径(
    $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);