断続的な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プロセスからのロックが原因で、名前変更が1回または2回失敗しました。

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>

前述のように、これはマシン上で断続的に見られますが、問題が発生するとそれが持続します。

回答:


172

追加してみてください

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

あなたの<appender />要素に。これは、log4netがファイルをロックし、ファイルに書き込み、書き込み操作ごとにロックを解除することを意味するため、パフォーマンスに影響があります(デフォルトの動作では、ロックを取得して長時間保持します)。

デフォルトの動作の1つの意味は、同じマシンで実行されている複数のワーカープロセスの下で実行されているWebサイトでそれを使用している場合、それぞれが無期限にそのロックを取得して保持しようとし、そのうちの2つは失うだけです。ロックモデルを最小ロックに変更すると、この問題を回避できます。

(デバッグ時には、異常な終了と多くの新しいワーカープロセスの起動がまさに起こりそうなタイプのことです。)

幸運を!


ロガーが断続的に機能していた理由について、頭を悩ませる手間を省きました。ワーカープロセスをアプリプールに追加しました。
RhinoDevX64 2012年

私はこれをサービスで使用しています。この変更に加えて、サービスを実行したユーザーは必要に応じて書き込み権限も実行しました。ありがとう!
LowTide

おかげで、多くの時間を節約できました。
Siva

2
私はファイルを読みたいだけですが、log4netは読み取りもロックします...書き込みと読み取りを共有するためだけにロックする可能性があります
JobaDiniz

37

また、log4net FAQにも注意してください

複数のプロセスで同じファイルにログを記録するにはどうすればよいですか?

提供されている代替手段のいずれかを試す前に、複数のプロセスで同じファイルにログを記録する必要があるかどうかを自問してから、実行しないでください;-)。

FileAppenderは、このユースケースにプラグ可能なロックモデルを提供しますが、既存のすべての実装には問題と欠点があります。

デフォルトでは、FileAppenderはログを記録している間、ログファイルに排他的な書き込みロックをかけます。これにより、他のプロセスがファイルに書き込むことができなくなります。このモデルは、Linuxの(少なくとも一部のバージョンでは)Monoで故障することが知られており、別のプロセスがログファイルにアクセスしようとするとすぐに、ログファイルが破損する可能性があります。

MinimalLockは、ログの書き込み中にのみ書き込みロックを取得します。 これにより、パフォーマンスが大幅に低下しますが、複数のプロセスが同じファイルへの書き込みをインターリーブできます。

InterProcessLockはファイルをまったくロックしませんが、システム全体のMutexを使用して同期します。これは、すべてのプロセスが連携している(そして同じロックモデルを使用している)場合にのみ機能します。書き込まれるすべてのログエントリに対してMutexを取得して解放すると、パフォーマンスが低下しますが、MinimalLockを使用するよりもMutexを使用することをお勧めします。

複数のプロセスがログファイルのローリングを同時に開始しようとする可能性があるため、RollingFileAppenderを使用すると状況がさらに悪化します。RollingFileAppenderは、ファイルのローリング時にロックモデルを完全に無視します。ローリングファイルは、このシナリオと互換性がありません。

より良い代替手段は、プロセスをRemotingAppendersに記録させることです。RemoteLoggingServerPlugin(またはIRemoteLoggingSink)を使用すると、プロセスはすべてのイベントを受け取り、それらを単一のログファイルに記録できます。例の1つは、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
マイクチェンバレン

@MikeChamberlain OPによれば(回答については彼のコメントを参照)、log4netを使用してログに記録する複数のワーカーが同時に作業します。したがって、この問題は適切です。
ビスケット2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.