次のようなことができますか:
-Djava.util.logging.loglevel=FINE
明らかにそれは機能しませんが、アイデアは理解できます。そのようなものはありますか? それとも、プロパティ ファイルを作成する必要がありますか?
ベストアンサー1
要約:
Java-9+ の場合は、メソッドの先頭に次のコードを配置しますmain
:
(Java-8 以前については下部を参照してください)
final var cmdLineVal = System.getProperty("java.util.logging.loglevel");
if (cmdLineVal != null) {
LogManager.getLogManager().updateConfiguration(
(key) -> (oldVal, newVal) ->
key.equals(".level") || key.equals("java.util.logging.ConsoleHandler.level")
? cmdLineVal : newVal
);
}
main
変更できない場合の説明と回避策:
一般的には、java.util.logging
システムプロパティを使用して設定することはありません( などのいくつかの例外がありますjava.util.logging.SimpleFormatter.format
)。代わりに、グローバルログマネージャーシングルトン インスタンスは、ロギング サブシステムの構成を担当し、デフォルトでは からプロパティを読み込みます${JAVA_HOME}/conf/logging.properties
。この動作を微調整する方法はいくつかあります。
java.util.logging.config.file
代替のログ記録構成プロパティ ファイルへのパスをシステム プロパティに指定します。- 設定プロセスを完全にオーバーライドするクラス名を持つシステムプロパティを提供します(通常は、ログ設定プロパティを持つ
java.util.logging.config.class
カスタムを提供することによって)InputStream
設定を読み込む(is))。 - 使用LogManager.updateConfiguration(マッパー)方法 (ジャワ9以降)を使用して、選択したプロパティのみを上書きします。この方法では既存のプロパティのみを上書きでき、新しいプロパティを追加することはできません(そのためには、より面倒な方法があります)。updateConfiguration(入力ストリーム、マッパー)を使用する必要があります。
したがって、グローバル ルート ログ レベルをオーバーライドする場合は、メソッドupdateConfiguration(mapper)
の先頭のどこかで使用するのが最も簡単でしょうmain
。明示的に構成されていない子ロガーのデフォルトとしてプロパティ (空の文字列ルート ロガーのレベル)LogManager
を使用する.level
ので、java.util.logging.loglevel
OP のシステム プロパティを使用すると、次のようになります。
final var cmdLineVal = System.getProperty("java.util.logging.loglevel");
if (cmdLineVal != null) {
LogManager.getLogManager().updateConfiguration(
(key) -> (oldVal, newVal) ->
key.equals(".level")
? cmdLineVal : newVal
);
}
デフォルトのログ設定の場合、上記の設定ではFINE
コンソールにログエントリを出力するのに十分ではないことに注意してください。コンソールハンドラデフォルトでは、出力INFO
以上です。これを変更するには、java.util.logging.ConsoleHandler.level
ログ記録構成プロパティもオーバーライドする必要があります。これに同じシステム プロパティを再度使用する場合は、以下のように引数を変更する必要がありますupdateConfiguration
。
final var cmdLineVal = System.getProperty("java.util.logging.loglevel");
if (cmdLineVal != null) {
LogManager.getLogManager().updateConfiguration(
(key) -> (oldVal, newVal) ->
key.equals(".level")
|| key.equals("java.util.logging.ConsoleHandler.level")
? cmdLineVal : newVal
);
}
メソッドを変更できない場合はmain
、前述のjava.util.logging.config.class
プロパティを次のようにクラスを指すように定義できます。-Djava.util.logging.config.class=com.example.MyJulConfigurator
これにより、ログ設定のタスクがこのクラスのコンストラクタに委譲されます。このようなコンストラクタでは、まず通常の方法でファイルから設定を読み込むことができます(設定の読み取り()メソッド) を実行し、前のスニペットのコードを使用します。
public MyJulConfigurator() throws IOException {
System.clearProperty("java.util.logging.config.class");
LogManager.getLogManager().readConfiguration();
// the same code as in the previous snippet:
final var cmdLineVal = System.getProperty("java.util.logging.loglevel");
if (cmdLineVal != null) {
LogManager.getLogManager().updateConfiguration(
(key) -> (oldVal, newVal) ->
key.equals(".level") || key.equals("java.util.logging.ConsoleHandler.level")
? cmdLineVal : newVal
);
}
}
最後に、ログ設定に対するアドホックなコマンドライン変更を簡単にするための簡単なヘルパー関数を最近作成しました。ログレベルをシステムプロパティで上書きする(新しいログプロパティの追加もサポートしています)。
@TWiStErRobが述べたように、コメントjul-utils
、プロジェクトの依存関係として含む必要すらありません。クラスパスに追加するだけです(中央) を実行して、必要なシステム プロパティを定義します。
java -cp /path/to/jul-utils.jar:${CLASSPATH} \
-Djava.util.logging.config.class=pl.morgwai.base.jul.JulConfigurator \
-Djava.util.logging.overrideLevel=,java.util.logging.ConsoleHandler,com.third.party.talkative.lib \
-D.level=FINE \
-Djava.util.logging.ConsoleHandler.level=FINE \
-Dcom.third.party.talkative.lib.level=SEVERE \
${MY_JAVA_APP_MAINCLASS_AND_ARGUMENTS}
Java-8 以前の概要:
- 設定ファイルを手動で解析し
Properties
て負荷(ある)(見るここLogManager
どのファイルを読み取るかを決定する方法) .level
およびの値を置換java.util.logging.ConsoleHandler.level
するsetProperty(キー、値)システムプロパティから取得した値- 更新されたプロパティ
ByteArrayOutputStream
をストア(os, null) - 包む基礎データ
ByteArrayInputStream
(参照:この議論)に渡します設定を読み込む(is)
以前と同様に、メソッド内またはシステム プロパティmain
によって指定されたクラスのコンストラクター内で実行できます。java.util.logging.config.class