如何在运行时更改 NLog 规则目标?
How can I change NLog rule target during runtime?
我有原来的配置:
<rules>
<logger name="Logger" minlevel="Trace" writeTo="FileLog,syslog" />
</rules>
它将打印到文件并发送到服务器。
我希望在运行时更改目标,有时更改为 FileLog,有时更改为 syslog,有时更改为两者。
有没有可编程的方式?
两个选项:启用配置的自动重新加载(<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>
您现在可以使用 FindRuleByName
和 RemoveRuleByName
编辑 <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
请注意,当 "rule name" 不唯一时,第一条规则将与该名称一起使用。
编辑目标
有布局
上面的问题讨论的是"change target during runtime",这并不完全是上面描述的,因为那是关于日志规则的。
您还可以编辑目标,这样更容易。
如果目标具有 Layoutable 值(在带有 Layout
的文档中可见),您可以使用布局渲染器,例如context 类 like ${gdc} (global context)
<target xsi:type="Console"
name="String"
layout="Layout"
...
encoding="Encoding"
...
具有可布局的布局
所以我们可以这样做:
<target name="target1" xsi:type="Console" layout="${gdc:myLayout}"/>
在代码中
GlobalDiagnosticsContext.Set("MyLayout", "${message} ${exception");
无布局
如果它不可布局,例如控制台目标中的 "encoding",你可以这样做:
var config = LogManager.Configuration;
config.FindTargetByName<ConsoleTarget>("target1").Encoding = Encoding.ASCII;
LogManager.Configuration = config; // Apply new config
更新:扩展了更多示例、变体并更新为最新建议。
我有原来的配置:
<rules>
<logger name="Logger" minlevel="Trace" writeTo="FileLog,syslog" />
</rules>
它将打印到文件并发送到服务器。
我希望在运行时更改目标,有时更改为 FileLog,有时更改为 syslog,有时更改为两者。 有没有可编程的方式?
两个选项:启用配置的自动重新加载(<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>
您现在可以使用 FindRuleByName
和 RemoveRuleByName
<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
请注意,当 "rule name" 不唯一时,第一条规则将与该名称一起使用。
编辑目标
有布局
上面的问题讨论的是"change target during runtime",这并不完全是上面描述的,因为那是关于日志规则的。
您还可以编辑目标,这样更容易。
如果目标具有 Layoutable 值(在带有 Layout
的文档中可见),您可以使用布局渲染器,例如context 类 like ${gdc} (global context)
<target xsi:type="Console"
name="String"
layout="Layout"
...
encoding="Encoding"
...
具有可布局的布局
所以我们可以这样做:
<target name="target1" xsi:type="Console" layout="${gdc:myLayout}"/>
在代码中
GlobalDiagnosticsContext.Set("MyLayout", "${message} ${exception");
无布局
如果它不可布局,例如控制台目标中的 "encoding",你可以这样做:
var config = LogManager.Configuration;
config.FindTargetByName<ConsoleTarget>("target1").Encoding = Encoding.ASCII;
LogManager.Configuration = config; // Apply new config
更新:扩展了更多示例、变体并更新为最新建议。