我正在创建一个控制台应用程序,它可以导入一些不同类型的数据。要导入的数据类型由参数指定。对于每种类型的导入,我创建了一个记录器和一个指定了不同文件名的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使用哪些记录器并忽略其他记录器?
答案 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提出的回退可能是最有效的选择,因为它将避免对日志文件的独占锁定。您仍将拥有在解析配置后立即创建的日志文件。