Javaでデフォルトのログレベルを設定するためのコマンドラインオプションはありますか?質問する

Javaでデフォルトのログレベルを設定するためのコマンドラインオプションはありますか?質問する

次のようなことができますか:

-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.loglevelOP のシステム プロパティを使用すると、次のようになります。

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 以前の概要:

  1. 設定ファイルを手動で解析しProperties負荷(ある)(見るここLogManagerどのファイルを読み取るかを決定する方法)
  2. .levelおよびの値を置換java.util.logging.ConsoleHandler.levelするsetProperty(キー、値)システムプロパティから取得した値
  3. 更新されたプロパティByteArrayOutputStreamストア(os, null)
  4. 包む基礎データByteArrayInputStream(参照:この議論)に渡します設定を読み込む(is)

以前と同様に、メソッド内またはシステム プロパティmainによって指定されたクラスのコンストラクター内で実行できます。java.util.logging.config.class

おすすめ記事