web-dev-qa-db-ja.com

log4jログレベルの動的な変更

Log4jのログレベルを動的に変更するためのさまざまなアプローチを教えてください。アプリケーションを再デプロイする必要はありません。その場合、変更は永続的ですか?

117
Ravi

ログレベルの変更は簡単です。構成の他の部分を変更すると、より詳細なアプローチが行われます。

LogManager.getRootLogger().setLevel(Level.DEBUG);

変更は、Loggerのライフサイクルを通して永続的です。再初期化では、実行時にレベルを設定してもレベルの変更が保持されないため、構成が読み取られて使用されます。

UPDATE:Log4j 2を使用している場合、 documentation ごとにsetLevelへの呼び出しを削除する必要があります。実装クラスを介して達成されます。

Logger.setLevel()または同様のメソッドの呼び出しは、APIではサポートされていません。アプリケーションはこれらを削除する必要があります。同等の機能がLog4j 2実装クラスで提供されますが、アプリケーションがLog4j 2内部の変更の影響を受けやすくなる場合があります。

81
Aaron McIver

ファイルウォッチドッグ

Log4jは、log4j.xmlファイルの構成変更を監視できます。 log4jファイルを変更すると、log4jは変更に応じてログレベルを自動的に更新します。詳細については、org.Apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long)のドキュメントを参照してください。チェック間のデフォルトの待機時間は60秒です。ファイルシステム上の構成ファイルを直接変更するため、これらの変更は永続的です。必要なことは、DOMConfigurator.configureAndWatch()を1回呼び出すことだけです。

注意:configureAndWatchメソッドは、スレッドリークのため、J2EE環境で使用するには安全ではありません

JMX

ログレベルを設定する(または一般的に再構成する)log4jの別の方法は、JMXを使用することです。 Log4jは、そのロガーをJMX MBeanとして登録します。アプリケーションサーバーMBeanServerコンソール(またはJDKのjconsole.exe)を使用して、個々のロガーをそれぞれ再構成できます。これらの変更は永続的ではなく、アプリケーション(サーバー)を再起動した後、構成ファイルで設定された構成にリセットされます。

自作

アーロンが説明したように、ログレベルをプログラムで設定できます。それをあなたが望むようにあなたのアプリケーションに実装することができます。たとえば、ユーザーまたは管理者がログレベルを変更し、ロガーでsetLevel()メソッドを呼び出すGUIを使用できます。どこかで設定を保持するかどうかはあなた次第です。

85
mhaller

Log4j2は、所定の間隔でlog4j 2。xmlファイル(または同等のもの)をスキャンすることにより、構成を更新するように構成できます。構成タグに「monitorInterval」パラメーターを追加するだけです。サンプルのlog4j 2。xmlファイルの2行目を参照してください。これは、最後のログイベントから5秒以上経過した場合に、構成を再スキャンするようにlog4jに指示します。

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="warn" monitorInterval="5" name="tryItApp" packages="">

    <Appenders>
        <RollingFile name="MY_TRY_IT"
                     fileName="/var/log/tryIt.log"
                     filePattern="/var/log/tryIt-%i.log.gz">
            <Policies>
                <SizeBasedTriggeringPolicy size="25 MB"/>
            </Policies>
            ...
        </RollingFile>
    </Appenders>


    <Loggers>
        <Root level="error">
            <AppenderRef ref="MY_TRY_IT"/>
        </Root>
    </Loggers>

</Configuration>

IDE内でTomcatインスタンスにデプロイしている場合、またはスプリングブートを使用している場合、この作業を行うための追加の手順があります。これはここではやや範囲外のようで、おそらく別の質問に値するでしょう。

5

Log4j 1.xを使用する場合、DOMConfiguratorを使用して、XMLログ構成の定義済みセット(通常使用用とデバッグ用)のいずれかを送信するのが最良の方法であることがわかりました。

これらを利用するには、次のようにします。

  public static void reconfigurePredefined(String newLoggerConfigName) {
    String name = newLoggerConfigName.toLowerCase();
    if ("default".equals(name)) {
      name = "log4j.xml";
    } else {
      name = "log4j-" + name + ".xml";
    }

    if (Log4jReconfigurator.class.getResource("/" + name) != null) {
      String logConfigPath = Log4jReconfigurator.class.getResource("/" + name).getPath();
      logger.warn("Using log4j configuration: " + logConfigPath);
      try (InputStream defaultIs = Log4jReconfigurator.class.getResourceAsStream("/" + name)) {
        new DOMConfigurator().doConfigure(defaultIs, LogManager.getLoggerRepository());
      } catch (IOException e) {
        logger.error("Failed to reconfigure log4j configuration, could not find file " + logConfigPath + " on the classpath", e);
      } catch (FactoryConfigurationError e) {
        logger.error("Failed to reconfigure log4j configuration, could not load file " + logConfigPath, e);
      }
    } else {
      logger.error("Could not find log4j configuration file " + name + ".xml on classpath");
    }
  }

適切な構成名でこれを呼び出し、クラスパスにテンプレートを配置することを確認してください。

2
ISparkes

この回答では、ログレベルを動的に変更することはできません。サービスを再起動する必要があります。サービスを正常に再起動する場合は、以下のソリューションを使用してください

Log4jのログレベルを変更するためにこれを行いましたが、うまくいきました。ドキュメントを参照していません。このシステムプロパティ値を使用して、ログファイル名を設定しました。同じ手法を使用してログレベルも設定しましたが、機能しました

これをJVMパラメーターとして渡しました(Java 1.7を使用)

申し訳ありませんが、これはロギングレベルを動的に変更しないため、サービスの再起動が必要です

Java -Dlogging.level=DEBUG -cp xxxxxx.jar  xxxxx.Java

log4j.propertiesファイルに、このエントリを追加しました

log4j.rootLogger=${logging.level},file,stdout

私は試した

 Java -Dlogging.level=DEBUG -cp xxxxxx.jar  xxxxx.Java
 Java -Dlogging.level=INFO-cp xxxxxx.jar  xxxxx.Java
 Java -Dlogging.level=OFF -cp xxxxxx.jar  xxxxx.Java

すべてうまくいきました。お役に立てれば!

私はpom.xmlにこれらの次の依存関係があります

<dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
</dependency>

<dependency>
    <groupId>log4j</groupId>
    <artifactId>Apache-log4j-extras</artifactId>
    <version>1.2.17</version>
</dependency>
2
Anandkumar