Java 9プラットフォームロギングAPI

1前書き

このチュートリアルでは、Java 9で新しく導入されたLogging APIを調べ、最も一般的なケースをカバーするためにいくつかの例を実装します。

このAPIは、すべてのプラットフォームログを処理し、ライブラリやアプリケーションによってカスタマイズ可能なサービスインタフェースを公開するための共通のメカニズムを提供するためにJavaで導入されました。アプリケーション、およびプロジェクトの依存関係を減らすことができます。

2カスタム実装の作成

このセクションでは、新しいロガーを作成するために実装しなければならないLogging APIの主なクラスを紹介します。すべてのログをコンソールに出力する単純なロガーを実装することによってこれを実現します。

2.1. Logger を作成する

作成しなければならない主なクラスは Logger です。このクラスは System.Logger インターフェースとこれら4つのメソッドを少なくとも実装する必要があります。

  • getName() :ロガーの名前を返します。 JDKで使用されます

名前でロガーを作成する ** isLoggable() :ロガーが有効になっているレベルを示します

  • log() :基本となるものにログを出力するメソッドです。

アプリケーションが使用しているシステム - この例ではコンソール。実装する2つの log() メソッドがあり、それぞれが異なるパラメータを受け取ります

実装がどのようになるか見てみましょう。

public class ConsoleLogger implements System.Logger {

    @Override
    public String getName() {
        return "ConsoleLogger";
    }

    @Override
    public boolean isLoggable(Level level) {
        return true;
    }

    @Override
    public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
        System.out.printf("ConsoleLogger[%s]: %s - %s%n", level, msg, thrown);
    }

    @Override
    public void log(Level level, ResourceBundle bundle, String format, Object... params) {
        System.out.printf("ConsoleLogger[%s]: %s%n", level,
          MessageFormat.format(format, params));
    }
}

私たちの ConsoleLogger クラスは上記の4つのメソッドをオーバーライドします。 getName() メソッドは String、 を返し、 isLoggable() メソッドはすべての場合において true を返します。最後に、コンソールに出力する2 log() メソッドがあります。

2.2. LoggerFinder を作成する

ロガーを作成したら、 ConsoleLogger のインスタンスを作成する LoggerFinder を実装する必要があります。

そのためには、抽象クラス System.LoggerFinder を拡張し、 getLogger() メソッドを実装する必要があります。

public class CustomLoggerFinder extends System.LoggerFinder {

    @Override
    public System.Logger getLogger(String name, Module module) {
        return new ConsoleLogger();
    }
}

この場合、常に ConsoleLogger が返されます。

  • 最後に、 LoggerFinder をサービスとして登録する必要があります。これにより、JDKによって検出されます。実装を提供しない場合は、 SimpleConsoleLogger がデフォルトで使用されます。

実装をロードするためにJDKによって使用されるメカニズムは ServiceLoader です。あなたはそれに関するより多くの情報をhttps://www.baeldung.com/java-spi[このチュートリアル]で見つけることができます。

Java 9を使用しているので、クラスをモジュールにパッケージ化し、 module-info.java ファイルにサービスを登録します。

module com.baeldung.logging {
    provides java.lang.System.LoggerFinder
      with com.baeldung.logging.CustomLoggerFinder;
    exports com.baeldung.logging;
}

Javaモジュールの詳細については、https://www.baeldung.com/java-9-modularityを参照してください。

2.3. 例をテストする

例をテストするために、アプリケーションとして機能する別のモジュールを作成しましょう。これは私たちのサービス実装を使う Main クラスだけを含みます。

このクラスは、 System.getLogger() メソッドを呼び出すことによって、 ConsoleLogger のインスタンスを取得します。

public class MainApp {

    private static System.Logger LOGGER = System.getLogger("MainApp");

    public static void main(String[]args) {
        LOGGER.log(Level.ERROR, "error test");
        LOGGER.log(Level.INFO, "info test");
    }
}
  • 内部的には、JDKは CustomLoggerFinder 実装を取得し、__ConsoleLoggerのインスタンスを作成します。

その後、このモジュール用の module-info ファイルを作成しましょう。

module com.baeldung.logging.app {
}

この時点で、私たちのプロジェクト構造は次のようになります。

├── src
│   ├── modules
│   │   ├── com.baeldung.logging
│   │   │   ├── com
│   │   │   │   └── baeldung
│   │   │   │       └── logging
│   │   │   │           ├── ConsoleLogger.java
│   │   │   │           └── CustomLoggerFinder.java
│   │   │   └── module-info.java
│   │   ├── com.baeldung.logging.app
│   │   │   ├── com
│   │   │   │   └── baeldung
│   │   │   │       └── logging
│   │   │   │           └── app
│   │   │   │               └── MainApp.java
│   │   │   └── module-info.java
└──

最後に、2つのモジュールをコンパイルして、それらを mods ディレクトリに配置します。

javac --module-path mods -d mods/com.baeldung.logging \
  src/modules/com.baeldung.logging/module-info.java \
  src/modules/com.baeldung.logging/com/baeldung/logging/** .java

javac --module-path mods -d mods/com.baeldung.logging.app \
  src/modules/com.baeldung.logging.app/module-info.java \
  src/modules/com.baeldung.logging.app/com/baeldung/logging/app/** .java

最後に、 app モジュールの Main クラスを実行しましょう。

java --module-path mods \
  -m com.baeldung.logging.app/com.baeldung.logging.app.MainApp

コンソールの出力を見ると、ログが ConsoleLogger を使用して印刷されていることがわかります。

ConsoleLogger[ERROR]: error test
ConsoleLogger[INFO]: info test

3外部ロギングフレームワークの追加

前の例では、すべてのメッセージをコンソールに記録していました。これは、デフォルトのロガーの動作と同じです。 ** Java 9のLogging APIの最も有用な使用方法の1つは、アプリケーションが使用しているのと同じロギングフレームワークにJDKログをルーティングすることです。これが、このセクションで行うことです。

SLF4Jをロギングファサードとして使用し、Logbackをロギングフレームワークとして使用する新しいモジュールを作成します。

前のセクションで基本について説明したので、今度は外部ロギングフレームワークを追加する方法に焦点を合わせることができます。

3.1. SLF4J を使用したカスタム実装

まず、インスタンスごとに新しいSLF4Jロガーを作成する別の Logger を実装します。

public class Slf4jLogger implements System.Logger {

    private final String name;
    private final Logger logger;

    public Slf4jLogger(String name) {
        this.name = name;
        logger = LoggerFactory.getLogger(name);
    }

    @Override
    public String getName() {
        return name;
    }

   //...
}
  • この __Logger org.slf4j.Logger __です。

他のメソッドについては、SLF4Jロガーインスタンスの実装に依存します。したがって、SLF4Jロガーが有効になっている場合は、 Logger が有効になります。

@Override
public boolean isLoggable(Level level) {
    switch (level) {
        case OFF:
            return false;
        case TRACE:
            return logger.isTraceEnabled();
        case DEBUG:
            return logger.isDebugEnabled();
        case INFO:
            return logger.isInfoEnabled();
        case WARNING:
            return logger.isWarnEnabled();
        case ERROR:
            return logger.isErrorEnabled();
        case ALL:
        default:
            return true;
    }
}

そしてログメソッドは使用されるログレベルに応じて適切なSLF4Jロガーメソッドを呼び出します。

@Override
public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
    if (!isLoggable(level)) {
        return;
    }

    switch (level) {
        case TRACE:
            logger.trace(msg, thrown);
            break;
        case DEBUG:
            logger.debug(msg, thrown);
            break;
        case INFO:
            logger.info(msg, thrown);
            break;
        case WARNING:
            logger.warn(msg, thrown);
            break;
        case ERROR:
            logger.error(msg, thrown);
            break;
        case ALL:
        default:
            logger.info(msg, thrown);
    }
}

@Override
public void log(Level level, ResourceBundle bundle, String format, Object... params) {
    if (!isLoggable(level)) {
        return;
    }

    switch (level) {
       //same as the previous switch
    }
}

最後に、 Slf4jLogger を使用する新しい LoggerFinder を作成しましょう。

public class Slf4jLoggerFinder extends System.LoggerFinder {
    @Override
    public System.Logger getLogger(String name, Module module) {
        return new Slf4jLogger(name);
    }
}

** 3.2. モジュール構成

すべてのクラスを実装したら、サービスをモジュールに登録し、SLF4Jモジュールの依存関係を追加しましょう。

module com.baeldung.logging.slf4j {
    requires org.slf4j;
    provides java.lang.System.LoggerFinder
      with com.baeldung.logging.slf4j.Slf4jLoggerFinder;
    exports com.baeldung.logging.slf4j;
}

このモジュールは次のような構造になります。

├── src
│   ├── modules
│   │   ├── com.baeldung.logging.slf4j
│   │   │   ├── com
│   │   │   │   └── baeldung
│   │   │   │       └── logging
│   │   │   │           └── slf4j
│   │   │   │               ├── Slf4jLoggerFinder.java
│   │   │   │               └── Slf4jLogger.java
│   │   │   └── module-info.java
└──

これで、前のセクションで行ったように、このモジュールを mods ディレクトリにコンパイルできます。

  • このモジュールをコンパイルするには、slf4j-api jarをmodsディレクトリに配置する必要があります。また、モジュール化されたバージョンのライブラリを使用することにも注意してください。 Maven Central]。

3.3. ログバックを追加する

ほぼ完了しましたが、Logbackの依存関係と設定を追加する必要があります。これを行うには、 logback-classic および logback-core のjarファイルを mods ディレクトリに配置します。

  • 以前と同様に、モジュール化されたバージョンのライブラリを使用していることを確認する必要があります** 。繰り返しますが、最新バージョンはhttps://search.maven.org/search?q=g:ch.qos.logback[Maven Central]にあります。

最後に、Logback設定ファイルを作成して mods ディレクトリに配置しましょう。

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss}[%thread]%-5level %logger{36} -- %msg%n
            </pattern>
        </encoder>
    </appender>

    <root>
        <appender-ref ref="STDOUT"/>
    </root>

</configuration>

3.4. 私たちのアプリケーションを実行する

この時点で、SLF4Jモジュールを使用して app を実行できます。

この場合、Logback設定ファイルも指定する必要があります。

java --module-path mods \
  -Dlogback.configurationFile=mods/logback.xml \
  -m com.baeldung.logging.app/com.baeldung.logging.app.MainApp

最後に、出力を確認すると、Logback設定を使用してログが印刷されたことがわかります。

2018-08-25 14:02:40[main]ERROR MainApp -- error test
2018-08-25 14:02:40[main]INFO  MainApp -- info test

4結論

この記事では、新しいPlatform Logging APIを使用してJava 9でカスタムロガーを作成する方法を説明しました。また、外部ロギングフレームワークを使用した例を実装しました。これは、この新しいAPIの最も有用な使用例の1つです。

いつものように、例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/core-java-9[GitHubで利用可能]です。