アプリケーションを再デプロイする必要がないように、log4jログレベルを動的に変更するためのさまざまなアプローチは何ですか。これらの場合、変更は永続的ですか?
アプリケーションを再デプロイする必要がないように、log4jログレベルを動的に変更するためのさまざまなアプローチは何ですか。これらの場合、変更は永続的ですか?
回答:
ログレベルの変更は簡単です。構成の他の部分を変更すると、より詳細なアプローチがもたらされます。
LogManager.getRootLogger().setLevel(Level.DEBUG);
変更は、のライフサイクルを通じて永続的Logger
です。再初期化時に、実行時にレベルの設定がレベルの変更を保持しないため、構成が読み取られて使用されます。
更新: Log4j 2を使用している場合はsetLevel
、ドキュメントごとにへの呼び出しを削除する必要があります。これは、実装クラスを介して実現できるためです。
logger.setLevel()または同様のメソッドの呼び出しは、APIではサポートされていません。アプリケーションはこれらを削除する必要があります。同等の機能がLog4j 2実装クラスで提供されますが、アプリケーションがLog4j 2内部の変更の影響を受けやすくなる可能性があります。
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
Log4jはlog4j.xml
、構成の変更についてファイルを監視できます。log4jファイルを変更すると、log4jは変更に応じてログレベルを自動的に更新します。詳細については、org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
)のドキュメントを参照してください。チェック間のデフォルトの待機時間は60秒です。ファイルシステム上の構成ファイルを直接変更するため、これらの変更は永続的です。DOMConfigurator.configureAndWatch()を1回呼び出すだけで済みます。
注意:configureAndWatchメソッドは、スレッドリークのため、J2EE環境での使用は安全ではありません。
ログレベルを設定する(または一般的に再構成する)log4jのもう1つの方法は、JMXを使用することです。Log4jは、ロガーをJMX MBeanとして登録します。アプリケーションサーバーのMBeanServerコンソール(またはJDKのjconsole.exe)を使用して、個々のロガーを再構成できます。これらの変更は永続的ではなく、アプリケーション(サーバー)を再起動した後、構成ファイルで設定された構成にリセットされます。
Aaronによって説明されているように、ログレベルをプログラムで設定できます。あなたはそれをあなたが望むようにあなたのアプリケーションに実装することができます。たとえば、ユーザーまたは管理者がログレベルを変更setLevel()
して、ロガーのメソッドを呼び出すGUIを作成できます。どこかに設定を保持するかどうかはあなた次第です。
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>
Tomcatインスタンスにデプロイする場合、IDE内、またはSpring Bootを使用する場合に、これを機能させるための追加の手順があります。これは、ここではやや範囲外と思われ、おそらく別の質問に値するでしょう。
この回答は、ロギングレベルを動的に変更するのに役立ちません。サービスを再起動する必要があります。サービスを正常に再起動している場合は、以下の解決策を使用してください
私はこれを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>
log4j 1.xでは、DOMConfiguratorを使用して、事前定義されたXMLログ構成のセットの1つ(たとえば、通常の使用とデバッグの1つ)を送信するのが最善の方法です。
これらを利用するには、次のような方法があります。
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");
}
}
適切な構成名でこれを呼び出し、テンプレートをクラスパスに置くことを確認してください。
私はこの方法を使用して「org.apache.http」ログの冗長性を減らすことに成功しました:
ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.apache.http");
logger.setLevel(Level.TRACE);
logger.setAdditive(false);
log4j 2 APIの場合は、
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
すべてのロガーのログレベルを変更する場合は、以下の方法を使用します。これにより、すべてのロガーが列挙され、ロギングレベルが指定されたレベルに変更されます。あなたがいることを確認してくださいしないでください持っているlog4j.appender.loggerName.Threshold=DEBUG
あなたの中にプロパティセットlog4j.properties
ファイルを。
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
次のコードスニペットを使用できます
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));