2011-04-18 12 views
54

log4jを使用してエラーやその他のシステム情報を記録しています。 INFOレベルで2回記録された情報から来ます。プログラムが起動するか、2回記録情報を失敗したがlog4j logging twice

public static void main(final String... args) throws Exception { 

    LOGGER.info("program started"); 
    try { 
     // try body codes 
    } catch (Exception ex) { 
     LOGGER.info("program start-up failed.",ex); 
    } 
} 

、いずれもその理由かもしれないものを見つけるために私を助けることができます。

+0

構成上の問題または初期化の問題が考えられます。 ロガーはどこで初期化しますか? Logger.getLogger(SomeClass.class)を2回呼び出すことはありませんか? いくつかの追加コードで、より多くの情報を提供することができます。 – MaSEL

答えて

75

メッセージがルートロガーによって一度ログされているように見え、特定のロガーによってもう一度ログに記録されるように見えます(アポインタが両方とも設定されている(プロパティファイルとコードの異なる場所にある可能性があります)。

これは、ロガーでの加算値をfalseに設定すると解決できます。 Log4j manualには、Appenders and Layoutセクションにadditivityが追加されています。チェックアウトしてください。

+2

これはどうやって解決しなければならないのですか、より大きな設定問題をマスクするバンドエイドですか? –

+1

ロガーがないと、何も記録されません。私がロガーを追加すると、それは2回記録されます。 additivityをfalseに設定すると、一度ログに記録されます。何が起きてる? –

+0

@DanielKaplanロガーに階層構造がある場合は、そうです。手動リンクから言い換えると、Fooを除くすべてのクラスのERRORメッセージだけが表示され、すべてのメッセージを表示したいとします。 Foo loggerの加算性をfalseに設定すると、すべてのERRORメッセージがルートに戻らず、再び印刷されます。 additivityがなければ、configはもっと複雑でメンテナンスが難しいので、これは正しいと言えます。 – whrrgarbl

29

atlantisに同意してください。

log4j.rootCategory=INFO, console 
log4j.logger.org.hibernate=INFO 

上記のプロパティ設定では、ダブルロギングが発生します。しかし

log4j.additivity.org.hibernate=false 

を追加

は、問題を修正しました。

この本の62ページを参照してください。それらの使用のXML形式の場合

+6

は「偽」ではなく「真」であるべきですか? –

+0

Googleブックはランダムに特定のページを非表示にしているようです。 [Here's](http://veerasundar.com/blog/2009/08/log4j-tutorial-additivity-what-and-why/)私が参考にしたブログ記事。いくつかの** log4j.category ... **エントリを含むより広範な例が含まれています –

2

Javaデバッガでプログラムを実行できる場合は、これらのダブルログ呼び出しのいずれかが発生するプログラムにブレークポイントを設定します。

デバッガでロガーオブジェクトを調べます。それがorg.apache.log4j.Logger(v 1.2.x)の場合、AppenderAttachableImplを持つことがあります。 AppenderAttachableImplにアペンダリストを問い合わせることができます。

複数のアペンダーが見つかった場合は、これが問題となる可能性があります。

2

単にあなたのコード(Reference)に

logger.setadditivity(false); 

を追加します。

コンソールにはダブルアサインがあります。アペンダーはシングルトンではないので、追加されます。つまり、カテゴリはすべてのアペンダをその祖先から継承します(デフォルトで)。あるカテゴリにアペンダーを追加し、他のアペンダーと同じ基本ストリーム(コンソール、同じファイルなど)に書き込むと、同じログメッセージがログに2回(またはそれ以上)表示されます。さらに、階層内の2つのカテゴリが同じアペンダー名を使用するように設定されている場合、Log4jはそのアペンダーに2回書き込みます。そのカテゴリに設定されています

0

additivityのプロパティを調整する可能性のある代替方法は、ロガーを最も具体的なものから最も一般的なものまで調べることです。次の例では、foo.bar.LoggingExampleClassで発生するすべてのログイベントに対して、コンソールでの二重ログの記録を期待しています。 foo.barから余分なコンソールアペンダーを削除することは安全です。LoggingExampleClass Loggerはすでにルートロガーによって保護されているので、

<Logger name="foo.bar.LoggingExampleClass" level="DEBUG"> 
    <AppenderRef ref="Console" /> <!-- THIS APPENDER COULD BE REMOVED --> 
    <AppenderRef ref="FooBarPackageLogging" /> 
</Logger> 

<Root level="WARN"> 
    <AppenderRef ref="Console" /> 
    <AppenderRef ref="MainLogFile" /> 
</Root> 

加算率調整アプローチとアペンダー調整アプローチの両方にはトレードオフがあります。加算性を無効にすると、望ましくないジェネリックレベルのロガーのアペンダーが使用されなくなる可能性があります。上記の例では、foo.bar.LoggingExampleClass Loggerのadditivity="false"プロパティを設定すると、ログイベントがルートロガーで参照されるMainLogFileに追加されないことを意味します。

一方、親アペンダーがより細かいロガーの影響を調べずに変更された場合、親アペンダーに依存すると問題になることがあります。たとえば、foo.bar.LoggingExampleClassロギングイベントをコンソールに書き込む必要があるとします。 foo.bar.LoggingExampleClass Loggerのコンソールアペンダが削除されていても、現在、これらはadditivityのために上記の設定例に含まれています。ただし、コンソールアペンダーも追加調整なしでルートロガーから削除された場合、要件はもはや満たされません。