2011-01-13 24 views
19

私は頻繁に作成/バックデフォルトにすべてをリセットするために必要な時間にlog4jのロガー、アペンダ、レベル、レイアウト、および時間を変更します。Log4j「デフォルト初期化手順」を再実行するには?実行時に

Log4jのシステムはよくのlog4jクラスがメモリにロードされるときに実行されるDefault Initialization Procedureを定義しています。実行時にプログラム全体でプロシージャ全体を再実行する方法はありますか?

は私がlog4jのドキュメントのいくつかのresetConfiguration()方法を見つけましたが、それらのいずれかがDefault Initialization Procedureが何をやるかどうかわからない:

  • BasicConfigurator.resetConfiguration();
  • Hierarchy.resetConfiguration();
  • LogManager.resetConfiguration();

のlog4j設定をリセットする上の任意の他の提案を歓迎し、より多くのです!ありがとうございました。 doConfigure方法についてdocumentationによると

+0

私はconfigureandwatchがあなたのニーズに合っていないと思います(http://logging.apache.org/log4j/1.2/faq.html#a3.6) – fglez

+0

"configureandwatch"は役に立ちません。変わらない。とにかくおかげさまで、ありがとう! – curd0

答えて

9

:ファイルから

読む構成。 既存の設定をクリアしたりがリセットされません。あなたは異なる動作が必要な場合は、コールresetConfiguration方法は、doConfigureを呼び出す前に。

私はLogManager.resetConfiguration()と呼び戻しPropertyConfigurator.configure()を呼び出すと、起動時と同じファイルであなたが望むことを行うことができます。

resetConfiguration()方法はHierarchyクラスに記載されています。

+0

それは私に働いた、ありがとう!また、LogManager.resetConfiguration()を呼び出さずに、PropertyConfigurator.configure(URL configURL) – Roger

+0

を呼び出すこともできます。LogManager.resetConfiguration()を呼び出さないと、以前のバージョンのlog4j.propertiesの設定が古くなる可能性があります。例えば新しいバージョンでは指定されていないロガーのレベル。 – spieden

7

この質問は、私は今日早く答えskiphoppy's questionに関連しています。

デフォルトの初期化は、クラスローディング時に一度だけ実行されるハードコードされたスタティックブロックであるため、AOP(アスペクト比)が必要です。これは、指向プログラミング)、より具体的には、静的初期化子を傍受するためのAspectJ。私はskiphoppyの他の質問にmy answerでそれを行う方法を説明しました。

これで、静的な初期化を傍受してLogManagerをトリックしてURLを伝えることができますが、コードブロック全体を再実行するには、ワーカーオブジェクトパターンという別のトリックが必要です。ここではサンプルコードがあり、説明は次のとおりです。

サンプル・アプリケーションクラス:

import org.apache.log4j.BasicConfigurator; 
import org.apache.log4j.Logger; 

public class Log4jDemo { 
    public static Runnable log4jDefaultInitCmd; 

    private static Logger logger = Logger.getLogger("scrum-master.de"); 

    public static void main(String[] args) throws InterruptedException { 
     BasicConfigurator.configure(); 
     logger.info("Hello world!"); 
     logger.info("Now sleeping for 2 sec..."); 
     Thread.sleep(2000); 
     logger.info("I am awake again!"); 
     if (log4jDefaultInitCmd != null) { 
      logger.info("Re-running log4j default initialisation"); 
      log4jDefaultInitCmd.run(); 
     } 
     logger.info("Done"); 
    } 
} 

アスペクト傍受静的初期化LogManagerの:

import org.apache.log4j.LogManager; 

public aspect Log4jAspect { 
    Object around() : staticinitialization(LogManager) { 
     System.out.println("log4j static initialisation"); 
     Log4jDemo.log4jDefaultInitCmd = new Runnable() { 
      @Override public void run() { 
       proceed(); 
      } 
     }; 
     Log4jDemo.log4jDefaultInitCmd.run(); 
     return null; 
    } 
} 

がどのように動作します:

AOPの一般的な概念を説明するのはこの答えの範囲を超えているので、理解しているか、それを理解するために何かを読むつもりであると思います。

  • Log4jAspectインターセプトLogManageraround()アドバイスは静的初期化。
  • アドバイス内では、proceed()コール(つまり、静的初期化の実行)は、匿名Runnableインスタンスによって実装されたワーカーオブジェクト内にパッケージ化されています。これは効果的に呼び出すことができるrun()メソッドを持つオブジェクトに呼び出しを効果的にラップします。
  • 静的な初期化をラップした後、Runnableインスタンスを別のクラスのパブリック静的メンバーに割り当てて、アスペクトの外部からアクセスできるようにします(例:Scalaのような動的言語では、これを字句スコープと呼びます)。 。
  • アドバイスの中で、ワーカーオブジェクトのrun()メソッドを呼び出すことによって静的な初期化を進めます。

これまでのところ、LogManagerクラスがロードされていて、アスペクトが存在しないかのように正しく初期化されました。しかし今ではLog4jDemo.mainを見てください:

  • 私たちはロガーを初期化し、いくつかのイベントを記録します。
  • 2秒間待っています(これまでに起こったことについてコンソール出力を確認するのに十分な時間です)。
  • 我々は続行し、は、ワーカーオブジェクトのrun()メソッドをもう一度呼び出すことによって、デフォルトの初期化を再発行します。

    log4j static initialisation 
    log4j: Trying to find [log4j.xml] using context classloader [email protected] 
    log4j: Trying to find [log4j.xml] using [email protected] class loader. 
    log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource(). 
    log4j: Trying to find [log4j.properties] using context classloader [email protected] 
    log4j: Using URL [file:/C:/Dokumente%20und%20Einstellungen/Robin/Eigene%20Dateien/java-src/dummy2/bin/log4j.properties] for automatic log4j configuration. 
    log4j: Reading configuration from URL file:/C:/Dokumente%20und%20Einstellungen/Robin/Eigene%20Dateien/java-src/dummy2/bin/log4j.properties 
    log4j: Parsing for [root] with value=[debug, stdout]. 
    log4j: Level token is [debug]. 
    log4j: Category root set to DEBUG 
    log4j: Parsing appender named "stdout". 
    log4j: Parsing layout options for "stdout". 
    log4j: Setting property [conversionPattern] to [%d{ABSOLUTE} %5p %c{1}:%L - %m%n]. 
    log4j: End of parsing for "stdout". 
    log4j: Setting property [target] to [System.out]. 
    log4j: Parsed "stdout" options. 
    log4j: Finished configuring. 
    12:41:22,647 INFO de:13 - Hello world! 
    0 [main] INFO scrum-master.de - Hello world! 
    12:41:22,663 INFO de:14 - Now sleeping for 2 sec... 
    16 [main] INFO scrum-master.de - Now sleeping for 2 sec... 
    12:41:24,663 INFO de:16 - I am awake again! 
    2016 [main] INFO scrum-master.de - I am awake again! 
    12:41:24,663 INFO de:18 - Re-running log4j default initialisation 
    2016 [main] INFO scrum-master.de - Re-running log4j default initialisation 
    log4j: Trying to find [log4j.xml] using context classloader [email protected] 
    log4j: Trying to find [log4j.xml] using [email protected] class loader. 
    log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource(). 
    log4j: Trying to find [log4j.properties] using context classloader [email protected] 
    log4j: Using URL [file:/C:/Dokumente%20und%20Einstellungen/Robin/Eigene%20Dateien/java-src/dummy2/bin/log4j.properties] for automatic log4j configuration. 
    log4j: Reading configuration from URL file:/C:/Dokumente%20und%20Einstellungen/Robin/Eigene%20Dateien/java-src/dummy2/bin/log4j.properties 
    log4j: Parsing for [root] with value=[debug, stdout]. 
    log4j: Level token is [debug]. 
    log4j: Category root set to DEBUG 
    log4j: Parsing appender named "stdout". 
    log4j: Parsing layout options for "stdout". 
    log4j: Setting property [conversionPattern] to [%d{ABSOLUTE} %5p %c{1}:%L - %m%n]. 
    log4j: End of parsing for "stdout". 
    log4j: Setting property [target] to [System.out]. 
    log4j: Parsed "stdout" options. 
    log4j: Finished configuring. 
    12:41:24,663 INFO de:21 - Done 
    2016 [main] INFO scrum-master.de - Done 
    

    Tadaa:あなたは、コマンドライン引数-Dlog4j.debug=trueを使用している場合

、次のように表示されます!ご覧のとおり、デフォルトの初期化は実際に2回実行されています。ログの出力はそれを証明します。たとえば、ログにUsing URL [file:/(...)]が2回表示されます。

結論:

これは特に良い方法はありませんが、それはハードコードされたが、APIの呼び出しを介してユーザーに公開されていないことが、より望ましい状況と比較に再発行のlog4jのデフォルトの初期化、事実はそのままで、このトリックが必要です。どのような状況でも、デフォルトの完全初期化ブロックを再実行する必要があるのは間違いありませんが、その質問には尋ねられたので、回避策を提案するのではなく、正確に答えたいと思いました。楽しい!

関連する問題