web-dev-qa-db-ja.com

Log4Net RollingFileAppenderがフラッシュしていませんIO少量のログのバッファ

HENRI COOKと同じ問題 について考えています。短い説明からわかる限り、それは Apache Jiraのバグ として報告されています。

本質的に私の問題は、アプリケーションがシャットダウンされたときにのみイベントがログに記録されることです(イベント後数週間でも)。ロギング量が非常に少ない場合に発生します。これはWindows Server 2008 R2で見られます。これにより、製造エラーをキャプチャして対応することができなくなります。

現在、アペンダーはバッファリング型ではありません。デフォルトでは、メッセージが追加されるたびに、基になるストリームでFlush()も呼び出します。

私の質問はなぜそれが洗い流さないのですか?そして、 プログラムですべてのアペンダーをフラッシュする 以外の対策はありますか? パルスアペンダー が実行可能な回避策だと思いますか?

アペンダー設定:

<appender name="RollingErrorFileAppender" type="log4net.Appender.RollingFileAppender">
  <param name="File" value="D:\LogFiles\zzzz\xxxxxx__ERROR" />
  <param name="AppendToFile" value="true" />
  <param name="DatePattern" value="_yyyyMMddHH&quot;.log&quot;" />
  <param name="RollingStyle" value="Date" />
  <param name="StaticLogFileName" value="false" />
  <filter type="log4net.Filter.LevelRangeFilter">
    <param name="LevelMin" value="ERROR" />
    <param name="LevelMax" value="FATAL" />
  </filter>
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%utcdate{yyyy-MM-dd HH:mm:ss.fff},[%thread],%level,%logger,%m%n"/>
  </layout>
</appender>

2013年6月19日更新

コードで動作を再現できませんでした。どんなに悪いことをしても、データは常にディスクにすぐに書き込まれます。ただし、重要な観察が行われました。ファイルへの最初の書き込みが1KiBより大きい場合、変更時間は後続の書き込みで更新されることはありません。ファイルが閉じられたときに閉じられたときにのみ更新されます。一方、最初の書き込みが短いワンライナーである場合、後続の書き込みは変更時刻を更新します。この動作は、log4netと手動の間で一貫していますIO操作、32ビットWinXPと64ビットW2k8R2の間、.NET 2.0、3.5と.NET 4.0の間。それでも問題は解決しませんが、少なくとも変な修正時間のパターンが理解できました。

ありがとう、ロブ

17
Rbjz

エラーレベルまたはより悪いログイベントのみに関心があり、そのトラフィックは幸運にもまれなので、すぐにフラッシュするようにアペンダーを構成することをお勧めします。

<param name="ImmediateFlush" value="true" />

これにより、すべてのログイベントでアペンダーをプログラムでフラッシュする必要がなくなります(ログイベントのサウンドからは機能しませんでした)。ここで、より多くのログレベルでアペンダーを開きたい場合は、もちろん、すべてのイベントをすぐにフラッシュすると、パフォーマンスの問題が大きくなる可能性があります。

[〜#〜]編集[〜#〜]

テストに使用した構成ファイルと簡単なメインプログラムを追加しました。次を使用すると、ログイベントがすぐにフラッシュされます。コメントに関しては、XMLからImmediateFlush行を取り除いて、デフォルトのtrue値がフラッシュに役立つことを確認することもできます。私の例では、望ましい動作を明示するために、この行をそのままにしました。

基本的なメインプログラム:

class Program
{
    static void Main(string[] args)
    {
        ILog log = LogManager.GetLogger(typeof(Program));
        XmlConfigurator.Configure(new FileInfo(@"C:\temp\logTest.config"));

        string msg;
        while ((msg = Console.ReadLine()) != "Done")
        {
            log.Error(msg);
        }

        LogManager.Shutdown();
    }
}

main progによって参照されるlogTest.config:

<log4net>
    <appender name="RollingErrorFileAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="C:\temp\log" />
        <param name="AppendToFile" value="true" />
        <param name="DatePattern" value="_yyyyMMddHH&quot;.log&quot;" />
        <param name="RollingStyle" value="Date" />
        <param name="StaticLogFileName" value="false" />
        <param name="ImmediateFlush" value="true" />
        <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="ERROR" />
            <param name="LevelMax" value="FATAL" />
        </filter>
        <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%utcdate{yyyy-MM-dd HH:mm:ss.fff},[%thread],%level,%logger,%m%n"/>
        </layout>
    </appender>
    <root>
        <level value="INFO" />
        <appender-ref ref="RollingErrorFileAppender" />
    </root>
</log4net>
29
Adam S