间歇 log4net RollingFileAppender 锁定文件问题

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

在使用 VisualStudio 进行开发和调试时,我们会在 VS 输出窗口中得到以下 log4net 错误消息:

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

该进程无法访问文件“ C: file 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" />

Our current workaround for the issue is to rename the last log file. We would of course expect this to fail (due to the aforementioned file lock), but it normally doesn't. Once or twice the rename has failed due to a lock from the aspnet_wp.exe process.

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>

正如前面提到的,我们在机器上看到这种情况时有发生,但是一旦发生这种情况就会持续下去。

63571 次浏览

加一下

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

to your <appender /> element. There is some performance impact because this means that log4net will lock the file, write to it, and unlock it for each write operation (as opposed to the default behavior, which acquires and holds onto the lock for a long time).

One implication of the default behavior is that if you're using it under a Web site that is being executed under multiple worker processes running on the same machine, each one will try to acquire and hold onto that lock indefinitely, and two of them are just going to lose. Changing the locking model to the minimal lock works around this issue.

(When debugging, ungraceful terminations and spinning up lots of new worker processes is exactly the type of thing that's likely to happen.)

Good luck!

如果你有的话

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

然后加

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

那么在滚动过程中就会出现错误。 The first process will create the new file and the rename the current file. 然后,接下来的进程将执行同样的操作,获取新创建的文件并覆盖新重命名的文件。 导致最后一天的 logfiel 为空。

还要注意 Log4net 常见问题解答:

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

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

FileAppender 为此用例提供了可插入锁定模型 现有的实现存在问题和缺点。

默认情况下,FileAppender 在日志上持有独占写锁 这样可以防止其他进程写入 这个模型是已知的故障与(至少在一些 Linux 上的 Mono 版本和日志文件可能很快就会损坏 另一个进程尝试访问日志文件。

MinimalLock 只在写入日志时获取写锁。 This allows multiple processes to interleave writes to the same file, 尽管在性能上有相当大的损失

InterProcessLock 根本不锁定文件,而是使用 系统范围的互斥。这将只有在所有进程合作(和 使用相同的锁定模式) 对于要写入的每个日志条目,将导致 性能,但是 Mutex 比 minalLock 更可取。

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

一个更好的选择是让您的进程登录到 使用 RemoteLoggingServerPlugin (或 IRemoteLoggingSink)进程可以接收所有事件并记录它们 其中一个示例演示如何使用 RemoteLoggingServerPlugin.