我该如何在运行时更改NLog规则目标?

4

我有原始配置:

<rules>
    <logger name="Logger" minlevel="Trace" writeTo="FileLog,syslog" />
</rules>

该程序将会同时输出到文件和发送到服务器。

我希望在运行时能够更改输出目标,有时输出到文件日志,有时输出到系统日志,有时同时输出到两者之中。 是否有一种可编程的方式实现这个要求?


我想编写像 DisableAllSyslogTargetsEnableAllTargetsEnableOnlySyslogTargets 这样的方法。 - Mike
1个回答

8
两种选择:启用配置文件的自动重新加载(<nlog autoreload="true")或更改配置文件。

或者通过编程实现:

编辑 <logger>

// remove syslog from first rule
var config = LogManager.Configuration;
config.LoggingRules[0].Targets.RemoveAt(1); 
LogManager.Configuration = config; // Apply new config

使用更多规则编辑<logger>

如果你有更多的规则,那么使用规则索引可能有点麻烦。对于这种情况,NLog添加了一个 ruleName选项 - 从NLog 4.6.4开始引入。

<rules>
    <logger name="Logger" rulename="rule1" minlevel="Warn" writeTo="FileLog" />
    <logger name="Logger" rulename="rule2" minlevel="Warn" writeTo="Syslog" />
</rules>

现在您可以使用FindRuleByNameRemoveRuleByName编辑<logger>

例如:


var config = LogManager.Configuration;
config.FindRuleByName("rule2").EnableLoggingForLevel(LogLevel.Debug); //enable level debug
config.RemoveRuleByName("rule1"); // Remove rule

LogManager.Configuration = config; // Apply new config

请注意,当“规则名称”不唯一时,将使用具有该名称的第一个规则。

编辑目标

使用布局

上面的问题谈到了“在运行时更改目标”,但这并不完全符合上述描述,因为那是关于日志规则的。

您还可以轻松地编辑目标。

如果目标具有可布局值(在文档中可见,使用Layout),则可以使用布局渲染器,例如上下文类,如${gdc}(全局上下文)

例如:控制台目标定义

 <target xsi:type="Console"
          name="String"
          layout="Layout"
          ... 
          encoding="Encoding"
          ...

具有可排版的布局

因此,我们可以这样做:

<target name="target1" xsi:type="Console"  layout="${gdc:myLayout}"/>

并且在代码中

GlobalDiagnosticsContext.Set("MyLayout", "${message} ${exception");

没有布局

如果它不能布局,例如控制台目标中的“编码”,则可以执行以下操作:

var config = LogManager.Configuration;
config.FindTargetByName<ConsoleTarget>("target1").Encoding = Encoding.ASCII;
LogManager.Configuration = config; // Apply new config

更新:增加了更多的例子和变化,并且按照最新的建议进行了更新。


为什么是0?为什么是1?如果配置文件具有一定的复杂性(多个目标,每个目标多个规则),会怎样呢? - a113nw
1
在这个问题中只有一个规则。现在有一种更简单的方法来处理多个规则。很快会更新答案。 - Julian
1
@4myle 已更新。如果这能回答你的问题,请告诉我 :) - Julian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接