间歇log4net RollingFileAppenderlocking的文件问题

我们在开发和生产机器上看到一个间歇性问题,我们的日志文件没有被logging到日志文件中。

在使用Visual Studio进行开发和debugging时,我们在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. 

configuration部分应该如下所示:

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

我们目前的解决方法是重命名最后一个日志文件。 我们当然期望这会失败(由于上述的文件locking),但通常不会。 由于来自aspnet_wp.exe进程的locking,一次或两次重命名失败。

我们的log4netconfiguration部分如下所示:

 <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]
"/> <footer value="[Footer]
"/> <conversionPattern value="%date %-5level %logger ${COMPUTERNAME} %property{UserHostAddress} [%property{SessionID}] - %message%newline"/> </layout> </appender> <root> <level value="INFO"/> <appender-ref ref="RollingLogFileAppender"/> </root> </log4net> 

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

尝试添加

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

到你的<appender />元素。 有一些性能影响,因为这意味着log4net将locking文件,写入,并为每个写入操作解锁(而不是默认的行为,获取并持有锁在很长一段时间)。

默认行为的一个含义是,如果你在同一台机器上运行的多个工作进程下正在执行的Web站点下使用它,则每个人将尝试无限期地获取并保持该锁,其中两个是只是会输。 将locking模型更改为最小locking可解决此问题。

(在debugging时,不正确的终止和转换大量新的工作进程正是可能发生的事情)。

祝你好运!

也请注意log4net FAQ :

我如何获得多个进程login到相同的文件?

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

FileAppender为这个用例提供可插入的locking模型,但所有现有的实现都有问题和缺点。

默认情况下,FileAppender在日志文件logging过程中保持独占的写入locking。 这可以防止其他进程写入文件。 这种模式已知可以在Linux上(至less在某些版本的)Mono上发生崩溃,一旦另一个进程尝试访问日志文件,日志文件可能会被破坏。

正在写入日志时,MinimalLock只获取写入locking。 这允许多个进程交叉写入同一文件,尽pipe性能有相当大的损失。

InterProcessLock根本不会locking文件,而是使用全系统互斥锁进行同步。 这只有在所有进程合作(并使用相同的locking模型)的情况下才有效。 每写入一个日志条目的互斥锁的获取和释放都会导致性能的下降,但互斥体优于使用MinimalLock。

如果使用RollingFileAppender,事情会变得更糟,因为多个进程可能会尝试同时开始滚动日志文件。 RollingFileAppender在滚动文件时完全忽略locking模型,滚动文件与这种情况根本不兼容。

更好的select是让您的进程login到RemotingAppenders。 使用RemoteLoggingServerPlugin(或IRemoteLoggingSink),进程可以接收所有事件并将其logging到单个日志文件中。 其中一个例子显示了如何使用RemoteLoggingServerPlugin。

如果你有

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

并添加

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

那么滚动发生时就会出现错误。 第一个进程将创build新文件并重命名当前文件。 然后下一步将执行相同的操作,并采用新创build的文件并覆盖新重命名的文件。 导致在最后一天的logfiel是空的。