Log4net和多个记录器到不同的文件

时间:2014-05-23 08:00:20

标签: .net concurrency log4net

我正在创建一个控制台应用程序,它可以导入一些不同类型的数据。要导入的数据类型由参数指定。对于每种类型的导入,我创建了一个记录器和一个指定了不同文件名的appender:

<logger name="ClientsImporter">
  <level value="INFO" />
  <appender-ref ref="ClientsImporter" />
</logger>

<logger name="PricesImporter">
  <level value="INFO" />
  <appender-ref ref="PricesImporter" />
</logger>

<appender name="ClientsImporter" type="log4net.Appender.RollingFileAppender">
  <file value="..\logs\ClientsImporter_log" />
  [...]
</appender>

<appender name="PricesImporter" type="log4net.Appender.RollingFileAppender">
  <file value="..\logs\ImbalancePricesImporter_log" />
  [...]
</appender>

<root>
  <level value="INFO" />
  <appender-ref ref="VisualStudioDebugOutput" />
  <appender-ref ref="ColoredConsoleAppender" />
</root>

在我的代码中,我为每个导入类型都有一个类,这个Logger的类实例创建如下:

internal readonly ILog Log = LogManager.GetLogger("ClientsImporter");

问题是显然log4net想要对所有appender的所有文件进行独占锁定。不仅是当前应用程序使用的那些。这是一个问题,因为一些导入可能彼此重叠(由同一程序的不同实例执行),然后log4net抛出错误,它无法获得对日志文件的独占锁定(即使那些不会被它使用)。

有没有办法告诉log4net使用哪些记录器并忽略其他记录器?

2 个答案:

答案 0 :(得分:1)

您可以使用lockingModel将文件锁定设置为MinimalLock:

<appender name="ClientsImporter" type="log4net.Appender.RollingFileAppender">
  <file value="..\logs\ClientsImporter_log" />
  **<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>**
  [...]
</appender>

答案 1 :(得分:1)

this answer我告诉OP,log4net对于其日志文件通常很贪心。创建:

  

只要在ActivateOptions()方法中初始化appender,就会创建该文件。从我看到你需要一个自定义FileAppender来处理你所有的业务规则。它需要

- override the default ActivateOptions method to prevent file creation
- override the Append method to create a new timestamped file when a message is logged
- use data passed in the LoggingEvent class (you have some properties available on the class) to retrieve the filename; you have to determine the filename before logging.
     

除非您希望从已经实现的行为中受益(例如模拟),否则我建议从FileAppender类中跳过继承并直接从TextWriterAppender类继承。

所以我认为 - 除非你想自定义appender的行为 - peer提出的回退可能是最有效的选择,因为它将避免对日志文件的独占锁定。您仍将拥有在解析配置后立即创建的日志文件。