ネイティブ実行可能ファイルへのロギングの追加

デフォルトでは、ネイティブ・イメージによって生成されたネイティブ実行可能ファイルは、java.util.logging.* APIを介したロギングをサポートしています。

デフォルトのロギング構成

ネイティブ実行可能ファイルのデフォルトのロギング構成は、JDKにあるlogging.propertiesファイルに基づいています。このファイルにより、INFO以上のレベルのメッセージのみを表示するjava.util.logging.ConsoleHandlerが構成されています。カスタム・ロギング構成は、次に示すように、実行可能ファイルのビルド時または実行時にロードできます。

追加のロギング・ハンドラが必要な場合は、対応するクラスをリフレクション用に登録する必要があります。たとえば、java.util.logging.FileHandlerを使用する場合は、次のリフレクション構成を指定します:

{
    "name" : "java.util.logging.FileHandler",
    "methods" : [
      { "name" : "<init>", "parameterTypes" : [] },
    ]
  }

詳細は、リフレクションのサポートに関する項を参照してください。

ビルド時のロガーの初期化

次の例に示すように、カスタムのlogging.properties構成ファイルを使用して、実行可能ファイルのビルド時にロガーを初期化できます。

  1. 次のJavaコードをLoggerBuildTimeInit.javaという名前のファイルに保存し、javacを使用してコンパイルします:
     import java.io.IOException;
     import java.util.logging.Level;
     import java.util.logging.LogManager;
     import java.util.logging.Logger;
    
     public class LoggerBuildTimeInit {
         private static final Logger LOGGER;
         static {
             try {
                 LogManager.getLogManager().readConfiguration(LoggerBuildTimeInit.class.getResourceAsStream("/logging.properties"));
             } catch (IOException | SecurityException | ExceptionInInitializerError ex) {
                 Logger.getLogger(LoggerBuildTimeInit.class.getName()).log(Level.SEVERE, "Failed to read logging.properties file", ex);
             }
             LOGGER = Logger.getLogger(LoggerBuildTimeInit.class.getName());
         }
    
         public static void main(String[] args) throws IOException {
             LOGGER.log(Level.WARNING, "Danger, Will Robinson!");
         }
     } 
    
  2. logging.propertiesリソース・ファイルをダウンロードし、LoggerBuildTimeInit.javaと同じディレクトリに保存します。

  3. ネイティブ実行可能ファイルをビルドして実行します

     native-image LoggerBuildTimeInit --initialize-at-build-time=LoggerBuildTimeInit
    
     ./loggerbuildtimeinit
    

    次のような出力が生成されます:

     WARNING: Danger, Will Robinson! [Wed May 18 17:20:39 BST 2022]
    

    これは、実行可能ファイルのビルド時にlogging.propertiesファイルが処理されることを示しています。このファイルはネイティブ実行可能ファイルに含める必要がないため、生成される実行可能ファイルのサイズが小さくなります。

    LoggerHolder.LOGGERもビルド時に初期化され、実行時にすぐに使用できるため、起動時間が改善されます。アプリケーションで実行時にカスタムのlogging.properties構成ファイルを処理する必要がないかぎり、このアプローチをお薦めします。

実行時のロガーの初期化

次の例に示すように、実行時にロガーを初期化することもできます。

  1. 次のJavaコードをLoggerRunTimeInit.javaという名前のファイルに保存し、javacを使用してコンパイルします:

     import java.io.IOException;
     import java.util.logging.Level;
     import java.util.logging.LogManager;
     import java.util.logging.Logger;
        
     public class LoggerRunTimeInit {
         public static void main(String[] args) throws IOException {
             LogManager.getLogManager().readConfiguration(LoggerRunTimeInit.class.getResourceAsStream("/logging.properties"));
             Logger logger = Logger.getLogger(LoggerRunTimeInit.class.getName());
             logger.log(Level.WARNING, "Danger, Will Robinson!");
         }
     }
    
  2. logging.propertiesリソース・ファイルをダウンロードし、LoggerRunTimeInit.javaと同じディレクトリに保存します。

  3. ネイティブ実行可能ファイルをビルドして実行します

     native-image LoggerRunTimeInit -H:IncludeResources="logging.properties"
    
     ./loggerruntimeinit
    

    次のような出力が生成されます:

     WARNING: Danger, Will Robinson! [Wed May 18 17:22:40 BST 2022]
    

    この場合、logging.propertiesファイルが実行時処理に使用可能であり、-H:IncludeResources=logging.propertiesオプションを通じて実行可能ファイルに含まれている必要があります。このオプションの詳細は、ネイティブ実行可能ファイルでのリソースの使用に関する項を参照してください。