间歇性的log4net RollingFileAppender锁定文件问题


113

我们在开发和生产机器上看到间歇性问题,因此我们的日志文件没有被登录。

使用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>

如前所述,我们在计算机上间歇性地看到了这种情况,但是一旦问题发生,问题仍然存在。

Answers:


172

尝试添加

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

到你的<appender />元素。这会对性能产生一些影响,因为这意味着log4net将锁定文件,对其进行写入并针对每个写入操作对其进行解锁(与默认行为相反,默认行为是获取并长时间保持该锁定)。

默认行为的一个暗示是,如果您在一个网站上使用它,而该网站正在同一台计算机上运行的多个工作进程下执行,则每个进程都会尝试无限期获取并持有该锁,其中两个是只会输。将锁定模型更改为最小锁定可以解决此问题。

(在调试时,不友好的终止和启动许多新的辅助进程正是可能发生的事情。)

祝好运!


记录器为何断断续续地工作,这使我免于烦恼。我将工作进程添加到了应用程序池中,du!
RhinoDevX64 2012年

我在服务中使用了此功能,除了进行此更改外,该服务的用户还根据需要运行了写入权限。谢谢!
LowTide 2012年

非常感谢,节省了很多时间。
西瓦

2
我只想读取文件,但log4net也会锁定以进行读取...它可能仅出于写入和共享读取而锁定
JobaDiniz

37

另请注意log4net常见问题解答

如何获得多个进程来登录到同一文件?

在开始尝试提供的任何替代方法之前,请问自己是否真的需要多个进程登录到同一文件,然后才不要;-)。

FileAppender为此用例提供了可插入的锁定模型,但是所有现有的实现都有问题和缺点。

默认情况下,FileAppender在日志文件记录时对其日志文件持有排他写锁定。这样可以防止其他进程写入文件。已知此模型会在Linux上与Mono兼容(至少在某些版本上),并且一旦另一个进程尝试访问日志文件,日志文件可能会损坏。

MinimalLock仅在写入日志时获得写入锁定。 这允许多个进程将写入交织到同一个文件中,尽管会造成性能上的巨大损失。

InterProcessLock根本不锁定文件,而是使用系统范围的Mutex进行同步。仅当所有进程协作(并使用相同的锁定模型)时,此方法才有效。对于要写入的每个日志条目,获取并释放Mutex都会导致性能下降,但是Mutex优于使用MinimalLock。

如果使用RollingFileAppender,情况会变得更糟,因为可能会有多个过程尝试同时开始滚动日志文件。RollingFileAppender在滚动文件时完全忽略锁定模型,因为滚动文件根本不兼容此方案。

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


6

如果你有

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

并添加

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

那么在滚动过程中会出现错误。第一个过程将创建新文件,并重命名当前文件。然后,下一个过程将执行相同操作,并获取新创建的文件并覆盖新重命名的文件。结果最后一天的日志文件为空。


1
仅当多个进程正在访问同一滚动文件时,才如此。在同一过程中是安全的。 hectorcorrea.com/blog/log4net-thread-safe-but-not-process-safe
Mike Chamberlain

@MikeChamberlain根据OP(请参阅他的评论以回答),将有多个工人同时工作,使用log4net进行记录。因此,此问题是相关的!
seebiscuit 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.