19

HENRICOOKと同じ問題について考えています。簡単な説明からわかる限り、ApacheJiraのバグとして報告されています。

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

現在、アペンダーはバッファリングのものではありません。デフォルトでは、メッセージが追加されるたびに、基になるストリームで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-06-19

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

ありがとう、ロブ

4

1 に答える 1

31

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

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

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

編集

構成ファイルと、テストに使用した単純なメイン プログラムを追加しました。以下を使用すると、ログイベントがすぐにフラッシュされることがわかります。あなたのコメントに関してはImmediateFlush、xml から行を削除して、デフォルト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();
    }
}

メイン プログラムによって参照される 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>
于 2013-02-27T18:09:04.987 に答える