log4net RollingFileAppender 间歇性锁定文件问题

发布于 2024-08-16 08:31:51 字数 1771 浏览 11 评论 0原文

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

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

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

We are seeing an intermittent issue on development and production machines whereby our log files are not getting logged to.

When running in development and debugging using Visual Studio we get the following log4net error messages in the VS output window:

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

The process cannot access the file 'C:\folder\file.log' because it is being used by another process.

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.

The configuration section should look like:

<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.

Our log4net configuration section is shown below:

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

As mentioned, we are seeing this intermittently on machines, but once the issue happens it persists.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不语却知心 2024-08-23 08:31:51

尝试添加

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

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

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

(调试时,不正常的终止和启动大量新的工作进程正是可能发生的事情。)

祝你好运!

Try adding

<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!

快乐很简单 2024-08-23 08:31:51

另请注意 log4net 常见问题解答

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

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

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

默认情况下,FileAppender 在日志上持有独占写锁
记录时记录文件。这会阻止其他进程写入
到文件。众所周知,该模型会崩溃(至少在某些情况下)
Linux 上的 Mono 版本和日志文件可能会立即损坏
另一个进程尝试访问日志文件。

MinimalLock 仅在写入日志时获取写锁。
这允许多个进程交叉写入同一文件,
尽管性能损失相当大。

InterProcessLock 根本不锁定文件,而是使用
系统范围的互斥体。这只有在所有进程合作的情况下才有效(并且
使用相同的锁定模型)。 Mutex 的获取和释放
对于每个要写入的日志条目将导致丢失
性能,但互斥锁优于使用 MinimalLock。

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

更好的选择是将您的进程记录到
远程处理Appender。使用 RemoteLoggingServerPlugin(或
IRemoteLoggingSink)一个进程可以接收所有事件并记录它们
到单个日志文件。其中一个示例展示了如何使用
远程日志服务器插件。

Also be aware of the log4net FAQ:

How do I get multiple process to log to the same file?

Before you even start trying any of the alternatives provided, ask
yourself whether you really need to have multiple processes log to the
same file, then don't do it ;-).

FileAppender offers pluggable locking models for this usecase but all
existing implementations have issues and drawbacks.

By default the FileAppender holds an exclusive write lock on the log
file while it is logging. This prevents other processes from writing
to the file. This model is known to break down with (at least on some
versions of) Mono on Linux and log files may get corrupted as soon as
another process tries to access the log file.

MinimalLock only acquires the write lock while a log is being written.
This allows multiple processes to interleave writes to the same file,
albeit with a considerable loss in performance.

InterProcessLock doesn't lock the file at all but synchronizes using a
system wide Mutex. This will only work if all processes cooperate (and
use the same locking model). The acquisition and release of a Mutex
for every log entry to be written will result in a loss of
performance, but the Mutex is preferable to the use of MinimalLock.

If you use RollingFileAppender things become even worse as several
process may try to start rolling the log file concurrently.
RollingFileAppender completely ignores the locking model when rolling
files, rolling files is simply not compatible with this scenario.

A better alternative is to have your processes log to
RemotingAppenders. Using the RemoteLoggingServerPlugin (or
IRemoteLoggingSink) a process can receive all the events and log them
to a single log file. One of the examples shows how to use the
RemoteLoggingServerPlugin.

穿越时光隧道 2024-08-23 08:31:51

如果您有

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

并添加,

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

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

If you have

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

and add

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

then there will be an error while the rolling happens.
The first process will create the new file and the rename the current file.
Then next proces will do the same and take the newly created file and overwrite the newly renamed file.
Resulting in the logfiel for the last day being empty.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文