间歇性log4net RollingFileAppender锁定文件问题

时间:2010-01-04 12:56:55

标签: locking log4net rollingfileappender

我们发现开发和生产机器上存在间歇性问题,导致我们的日志文件无法登录。

使用Visual Studio在开发和调试中运行时,我们在VS输出窗口中收到以下log4net错误消息:

log4net:ERROR [RollingFileAppender] Unable to acquire lock on file C:\folder\file.log.

该进程无法访问文件'C:\ folder \ file.log',因为它正由另一个进程使用。

log4net:ERROR XmlConfigurator: Failed to find configuration section 'log4net' in the application's .config file.
Check your .config file for the <log4net> and <configSections> elements.

配置部分应如下所示:

<section
  name="log4net"
  type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />

我们当前解决此问题的方法是重命名最后一个日志文件。我们当然希望这会失败(由于前面提到的文件锁定),但通常不会。由于 aspnet_wp.exe 进程锁定,重命名失败一次或两次。

我们的log4net配置部分如下所示:

<log4net>
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="C:\folder\file.log"/>
    <appendToFile value="true" />
    <datePattern value="yyyyMMdd" />
    <rollingStyle value="Date" />
    <maximumFileSize value="10MB" />
    <maxSizeRollBackups value="100" />
    <layout type="log4net.Layout.PatternLayout">
      <header value="[Header]&#xA;"/>
      <footer value="[Footer]&#xA;"/>
      <conversionPattern value="%date %-5level %logger ${COMPUTERNAME} %property{UserHostAddress} [%property{SessionID}] - %message%newline"/>
    </layout>
  </appender>
  <root>
    <level value="INFO"/>
    <appender-ref ref="RollingLogFileAppender"/>
  </root>
</log4net>

如上所述,我们在机器上间歇性地看到这种情况,但一旦问题发生,它就会持续存在。

3 个答案:

答案 0 :(得分:158)

尝试添加

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

到您的<appender />元素。存在一些性能影响,因为这意味着log4net将锁定文件,写入文件并为每次写入操作解锁(与默认行为相反,后者长时间获取并保留锁定。)

默认行为的一个含义是,如果您在同一台计算机上运行的多个工作进程下执行的Web站点下使用它,则每个站点将尝试无限期地获取并保留该锁定,并且他们只会失败。将锁定模型更改为最小锁定可解决此问题。

(调试时,不正常的终止并激活许多新的工作进程正是可能发生的事情。)

祝你好运!

答案 1 :(得分:32)

另请注意log4net FAQ

  

如何让多个进程登录到同一个文件?

     

在您开始尝试提供任何替代方案之前,请先询问   你自己是否真的需要有多个进程登录到   相同的文件,然后不要这样做; - )。

     

FileAppender为这个用例提供了可插拔的锁定模型   现有的实现有问题和缺点。

     

默认情况下,FileAppender在日志中保存独占写锁   文件正在记录。这可以防止其他进程写入   到文件。众所周知,这种模式会被打破(至少在某些方面   Linux上的Mono和日志文件可能会尽快损坏   另一个进程尝试访问日志文件。

     

MinimalLock仅在写入日志时获取写锁定。   这允许多个进程将写入交错到同一个文件,   虽然表现有相当大的损失。

     

InterProcessLock根本不锁定文件,而是使用a进行同步   系统范围的互斥体。这只有在所有流程合作时才有效(和   使用相同的锁定模型)。收购和发布Mutex   对于要写入的每个日志条目都将导致丢失   性能,但 Mutex优于使用MinimalLock。

     

如果使用RollingFileAppender,事情会变得更糟   进程可能会尝试同时开始滚动日志文件。   RollingFileAppender在滚动时完全忽略锁定模型   文件,滚动文件与此方案完全不兼容。

     

更好的选择是让您的进程登录   RemotingAppenders。使用RemoteLoggingServerPlugin(或   IRemoteLoggingSink)一个进程可以接收所有事件并记录它们   到一个日志文件。其中一个例子说明了如何使用   RemoteLoggingServerPlugin。

答案 2 :(得分:6)

如果你有

<staticLogFileName value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />

并添加

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

然后滚动发生时会出错。 第一个进程将创建新文件并重命名当前文件。 然后下一个进程将执行相同操作并获取新创建的文件并覆盖新重命名的文件。 导致最后一天的logfiel为空。