在运行时附加或分离 appender

Attach or detach appender at runtime

我正在为 log4net 使用 XML 配置。我有以下 appender-refs:

<root>
  <level value="ALL" />
  <appender-ref ref="ConsoleAppender" />
  <appender-ref ref="OldRollingLogAppender" />
</root>

(我还在 XML 中定义了这些附加程序——它们的具体实现应该无关紧要。)

我想在运行时删除 OldRollingLogAppender,然后创建并添加一个名为 NewRollingLogAppender 的新文件。我该怎么做呢?

一个最小的工作示例会很好。

您可以通过获取根记录器然后添加和删除附加程序来执行此操作:

删除:

var root = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
root.RemoveAppender(xxx);

添加:

var root = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
root.AddAppender(xxx);

您可以使用 root.Appenders 迭代附加程序列表 https://logging.apache.org/log4net/release/sdk/html/AllMembers_T_log4net_Repository_Hierarchy_RootLogger.htm

除了彼得的回答之外,我还必须执行以下操作:

1) 添加或删除之前,我不得不调用:

XmlConfigurator.Configure()

如果不先这样做,log4net 将不允许我删除任何旧的附加程序。

2) 添加新的 appender 时,我必须在运行时创建一个 appender — 在 C# 中 — 我无法从 XML 中提取它。 (虽然......这仍然是可能的......我可能只是做错了。)即,

PatternLayout patternLayout = new PatternLayout();
patternLayout.ConversionPattern = ...;
patternLayout.ActivateOptions();

RollingFileAppender serviceAppender = new RollingFileAppender();
serviceAppender.Name = "NewRollingLogAppender";
serviceAppender.File = ...;
serviceAppender.DatePattern = ...;
serviceAppender.AppendToFile = ...;
serviceAppender.StaticLogFileName = ...;
serviceAppender.Layout = patternLayout;
serviceAppender.ActivateOptions();

3) 我的所有 Adding/Removing 代码都完成后,我不得不调用:

(Hierarchy)(LogManager.GetRepository()).RaiseConfigurationCh‌​anged(EventArgs.Empt‌​y);

如果不这样做,log4net 将不会获取更改。

4) 我观察到,调用 XmlConfigurator.Configure() 时,它将创建并锁定与旧的(即待删除的)appender 关联的任何日志文件。我不希望这发生。为了解决这个问题,我必须创建一个自定义附加程序来覆盖 OpenFileCloseWriterAppend。这样,我可以在运行时决定是否 "opt-out"在调用 XmlConfigurator.Configure().

之前这个 appender