NLog に関する問題に出くわした可能性がありますが、最初にここで答えを確認すると思いました。
問題を再現するために、NLog ソースのクローンを作成して、遅延を追加して問題を引き起こすことができるようにしました。Visual Studio で開いたら、NLog ソース プロジェクトを参照し、いくつかの非常に単純なログ呼び出しを行うコンソール アプリケーションを追加しました。NLog.config は次のとおりです。
<nlog>
<targets>
<target name="buffer" type="BufferingWrapper">
<target name="logfile" type="File" fileName="log.txt"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
この時点まで、すべてが期待どおりに機能します。次のステップは、 のフラッシュ ロジックに遅延を挿入することFileTarget
です。(これが問題であることがわかった理由は、元々MailTarget
、メール サーバーへの接続中にしばらくハングする を使用していたためFileTarget
です。問題を簡単に再現できるように、代わりに here に置き換えました)。
FileTarget.cs を開き、メソッドを見つけますWrite(AsyncLogEventInfo[] logEvents)
。メソッドが次のように表示されるように、最初の行に挿入しThread.Sleep(5000)
ます。
protected override void Write(AsyncLogEventInfo[] logEvents)
{
Thread.Sleep(5000);
// ... omitted
}
ここで、コンパイルして再実行します。ログは書き込まれません。
私が知る限り、プロセスが終了したときにすべてのターゲットをフラッシュするロジックは、LogFactory.csFlush()
メソッドにあるデフォルトのタイムアウトが 15 秒の非同期メソッド呼び出しを使用します。これは明らかに超えていません。
ただし、NLog はThreadPool.QueueUserWorkItem()
(AsyncHelpers.cs にある) を利用して、各ターゲットのフラッシュを並行して調整します。これは単純に、この形式のメソッド呼び出しが への呼び出しにどのように反応するThread.Sleep()
か、または他の形式のブロッキング (私の元の問題のように、リモート サーバーへの接続など) にどのように反応するかという問題に要約できますか?
何か案は?