Java : FileHandler (ログ) - API使用例

FileHandler (Java SE 17 & JDK 17) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。


概要

クラス構成

FileHandlerは、ログをファイルへ出力するハンドラです。

設定により、

  • 1つのファイルへ、サイズ無制限にログを書き込む
  • サイズを制限した複数のファイルへ、ローテーションしてログを書き込む

ということが可能です。

追記モードはデフォルトで false となっています。
そのため、同じログファイルに対してプログラムを再起動してログを書き込むと、以前の内容を上書きしてしまいます。

プログラム再起動後も元のログを残して追記したい場合は、コンストラクタの append パラメータを true に指定します。

関連:ロギング(ログ出力)の基本

コンストラクタ

FileHandler ()

デフォルトのFileHandlerを構築します。

final var handler = new FileHandler();

System.out.println(handler.getLevel()); // ALL
System.out.println(handler.getFormatter()); // java.util.logging.XMLFormatter@2c83f1d1
System.out.println(handler.getFilter()); // null

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

logger.info("TEST LOG!");

// デフォルトだと、"%h/java%u.log" としてログファイルが作成されます。
// Windows 10の例 : C:\Users\xxxx\java0.log  (xxxxはユーザ名)

// --- PowerShell ---
//PS C:\Users\xxxx> cat .\java0.log
//<?xml version="1.0" encoding="UTF-8" standalone="no"?>
//<!DOCTYPE log SYSTEM "logger.dtd">
//<log>
//<record>
//  <date>2022-03-16T05:07:18.168677300Z</date>
//  <millis>1647407238168</millis>
//  <nanos>677300</nanos>
//  <sequence>1</sequence>
//  <logger>com.example.logging</logger>
//  <level>INFO</level>
//  <class>com.example.logging.FileHandlerTest</class>
//  <method>constructor</method>
//  <thread>1</thread>
//  <message>TEST LOG!</message>
//</record>
//</log>

FileHandler (String pattern)

指定されたファイル名に書き込むようにFileHandlerを初期化します。

final var pattern = Path.of("R:", "java-work", "log.txt");
System.out.println(pattern); // R:\java-work\log.txt

final var handler = new FileHandler(pattern.toString());
handler.setFormatter(new SimpleFormatter());

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

logger.info("TEST LOG : 1");
logger.info("TEST LOG : 2");

// --- PowerShell ---
//PS R:\java-work> ls -name
//log.txt
//
//PS R:\java-work> cat .\log.txt
//3月 16, 2022 2:52:35 午後 com.example.logging.FileHandlerTest$2 method
//情報: TEST LOG : 1
//3月 16, 2022 2:52:35 午後 com.example.logging.FileHandlerTest$2 method
//情報: TEST LOG : 2

一度、プログラムを終了してから下記のコードを実行します。
ログは追記ではなく、上書きで出力されます。(前回の出力内容は削除されます)

final var pattern = Path.of("R:", "java-work", "log.txt");
System.out.println(pattern); // R:\java-work\log.txt

final var handler = new FileHandler(pattern.toString());
handler.setFormatter(new SimpleFormatter());

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

logger.info("TEST LOG : 3");
logger.info("TEST LOG : 4");

// --- PowerShell ---
//PS R:\java-work> cat .\log.txt
//3月 16, 2022 2:52:35 午後 com.example.logging.FileHandlerTest$3 method
//情報: TEST LOG : 3
//3月 16, 2022 2:52:35 午後 com.example.logging.FileHandlerTest$3 method
//情報: TEST LOG : 4

もし追記で出力したい場合は、FileHandler(String pattern, boolean append)append パラメータを true にします。

FileHandler (String pattern, boolean append)

オプションの追加モードで、指定されたファイル名を書き込むFileHandlerを初期化します。

append が false のケースは、FileHandler(String pattern)と同等です。
そちらのAPI使用例もご参照ください。

final var pattern = Path.of("R:", "java-work", "log.txt");
System.out.println(pattern); // R:\java-work\log.txt

final var handler = new FileHandler(pattern.toString(), true);
handler.setFormatter(new SimpleFormatter());

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

logger.info("TEST LOG : 1");
logger.info("TEST LOG : 2");

// --- PowerShell ---
//PS R:\java-work> ls -name
//log.txt
//
//PS R:\java-work> cat .\log.txt
//3月 16, 2022 3:23:36 午後 com.example.logging.FileHandlerTest$4 method
//情報: TEST LOG : 1
//3月 16, 2022 3:23:36 午後 com.example.logging.FileHandlerTest$4 method
//情報: TEST LOG : 2

一度、プログラムを終了してから下記のコードを実行します。
ログは前回の内容に追記されます。

final var pattern = Path.of("R:", "java-work", "log.txt");
System.out.println(pattern); // R:\java-work\log.txt

final var handler = new FileHandler(pattern.toString(), true);
handler.setFormatter(new SimpleFormatter());

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

logger.info("TEST LOG : 3");
logger.info("TEST LOG : 4");

// --- PowerShell ---
//PS R:\java-work> cat .\log.txt
//3月 16, 2022 3:23:36 午後 com.example.logging.FileHandlerTest$4 method
//情報: TEST LOG : 1
//3月 16, 2022 3:23:36 午後 com.example.logging.FileHandlerTest$4 method
//情報: TEST LOG : 2
//3月 16, 2022 3:23:58 午後 com.example.logging.FileHandlerTest$5 method
//情報: TEST LOG : 3
//3月 16, 2022 3:23:58 午後 com.example.logging.FileHandlerTest$5 method
//情報: TEST LOG : 4

FileHandler (String pattern, int limit, int count)

一連のファイルに書き込むようにFileHandlerを初期化します。

// SimpleFormatterよりさらに見やすさを重視したフォーマッタを定義します。
class MoreSimpleFormatter extends Formatter {
    @Override
    public String format(LogRecord record) {
        return record.getLevel() + " : " + record.getMessage() + "\n";
    }
}

final var pattern = Path.of("R:", "java-work", "log_%g.txt");
System.out.println(pattern); // R:\java-work\log_%g.txt

final var handler = new FileHandler(pattern.toString(), 512, 3);
handler.setFormatter(new MoreSimpleFormatter());

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

for (int i = 0; i < 20; i++) {
    logger.info("TEST LOG : " + i);
}

// この時点でのファイルの状態。
//
// --- PowerShell ---
//PS R:\java-work> ls
// ...
//Mode                 LastWriteTime         Length Name
//----                 -------------         ------ ----
//-a---          2022/03/16    15:30            410 log_0.txt
//-a---          2022/03/16    15:30              0 log_0.txt.lck
//
//PS R:\java-work> cat .\log_0.txt
//INFO : TEST LOG : 0
//INFO : TEST LOG : 1
// ... 省略 ...
//INFO : TEST LOG : 18
//INFO : TEST LOG : 19

for (int i = 20; i < 40; i++) {
    logger.info("TEST LOG : " + i);
}

// この時点でのファイルの状態。
//
// --- PowerShell ---
//PS R:\java-work> ls
// ...
//Mode                 LastWriteTime         Length Name
//----                 -------------         ------ ----
//-a---          2022/03/16    15:30            315 log_0.txt
//-a---          2022/03/16    15:30              0 log_0.txt.lck
//-a---          2022/03/16    15:30            515 log_1.txt
//
//
//PS R:\java-work> cat .\log_0.txt
//INFO : TEST LOG : 25
//INFO : TEST LOG : 26
// ... 省略 ...
//INFO : TEST LOG : 38
//INFO : TEST LOG : 39
//
//PS R:\java-work> cat .\log_1.txt
//INFO : TEST LOG : 0
//INFO : TEST LOG : 1
// ... 省略 ...
//INFO : TEST LOG : 23
//INFO : TEST LOG : 24

for (int i = 40; i < 60; i++) {
    logger.info("TEST LOG : " + i);
}

// この時点でのファイルの状態。
//
// --- PowerShell ---
//PS R:\java-work> ls
// ...
//Mode                 LastWriteTime         Length Name
//----                 -------------         ------ ----
//-a---          2022/03/16    15:30            210 log_0.txt
//-a---          2022/03/16    15:30              0 log_0.txt.lck
//-a---          2022/03/16    15:30            525 log_1.txt
//-a---          2022/03/16    15:30            515 log_2.txt
//
//PS R:\java-work> cat .\log_0.txt
//INFO : TEST LOG : 50
//INFO : TEST LOG : 51
// ... 省略 ...
//INFO : TEST LOG : 58
//INFO : TEST LOG : 59
//
//PS R:\java-work> cat .\log_1.txt
//INFO : TEST LOG : 25
//INFO : TEST LOG : 26
// ... 省略 ...
//INFO : TEST LOG : 48
//INFO : TEST LOG : 49
//
//PS R:\java-work> cat .\log_2.txt
//INFO : TEST LOG : 0
//INFO : TEST LOG : 1
// ... 省略 ...
//INFO : TEST LOG : 23
//INFO : TEST LOG : 24

for (int i = 60; i < 80; i++) {
    logger.info("TEST LOG : " + i);
}

// この時点でのファイルの状態。
//
// --- PowerShell ---
//PS R:\java-work> ls
// ...
//Mode                 LastWriteTime         Length Name
//----                 -------------         ------ ----
//-a---          2022/03/16    15:30            105 log_0.txt
//-a---          2022/03/16    15:30              0 log_0.txt.lck
//-a---          2022/03/16    15:30            525 log_1.txt
//-a---          2022/03/16    15:30            525 log_2.txt
//
//PS R:\java-work> cat .\log_0.txt
//INFO : TEST LOG : 75
//INFO : TEST LOG : 76
//INFO : TEST LOG : 77
//INFO : TEST LOG : 78
//INFO : TEST LOG : 79
//
//PS R:\java-work> cat .\log_1.txt
//INFO : TEST LOG : 50
//INFO : TEST LOG : 51
// ... 省略 ...
//INFO : TEST LOG : 73
//INFO : TEST LOG : 74
//
//PS R:\java-work> cat .\log_2.txt
//INFO : TEST LOG : 25
//INFO : TEST LOG : 26
// ... 省略 ...
//INFO : TEST LOG : 48
//INFO : TEST LOG : 49

FileHandler (String pattern, int limit, int count, boolean append)

オプションの追加モードで、一連のファイルに書き込むようにFileHandlerを初期化します。

append パラメータが追加された以外は、FileHandler(String pattern, int limit, int count)と同等となります。
そちらのAPI使用例をご参照ください。

append パラメータについては FileHandler(String pattern, boolean append) の使用例をご参照ください。

FileHandler (String pattern, long limit, int count, boolean append)

オプションの追加モードで、一連のファイルに書き込むようにFileHandlerを初期化します。

パラメータの limit が long になったこと以外は FileHandler(String pattern, int limit, int count, boolean append) と同等です。

メソッド

void close ()

すべてのファイルを閉じます。

final var pattern = Path.of("R:", "java-work", "log.txt");
System.out.println(pattern); // R:\java-work\log.txt

final var handler = new FileHandler(pattern.toString());

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

logger.info("TEST LOG!");

// 不要になったハンドラを閉じます。
logger.removeHandler(handler);
handler.close();

System.out.print(Files.readString(pattern));

// 結果
// ↓
//<?xml version="1.0" encoding="UTF-8" standalone="no"?>
//<!DOCTYPE log SYSTEM "logger.dtd">
//<log>
//<record>
//  <date>2022-03-16T06:53:39.983693700Z</date>
//  <millis>1647413619983</millis>
//  <nanos>693700</nanos>
//  <sequence>1</sequence>
//  <logger>com.example.logging</logger>
//  <level>INFO</level>
//  <class>com.example.logging.FileHandlerTest</class>
//  <method>close</method>
//  <thread>1</thread>
//  <message>TEST LOG!</message>
//</record>
//</log>

void publish (LogRecord record)

LogRecordをフォーマットして発行します。

final var pattern = Path.of("R:", "java-work", "log.txt");
System.out.println(pattern); // R:\java-work\log.txt

final var handler = new FileHandler(pattern.toString()) {
    @Override
    public synchronized void publish(LogRecord logRecord) {
        // 意図的にメッセージを加工します。
        logRecord.setMessage(logRecord.getMessage() + ":override publish!");

        super.publish(logRecord);
    }
};
handler.setFormatter(new SimpleFormatter());

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.addHandler(handler);

logger.info("TEST LOG!");

System.out.print(Files.readString(pattern));

// 結果
// ↓
//3月 16, 2022 3:57:23 午後 com.example.logging.FileHandlerTest$7 method
//情報: TEST LOG!:override publish!

StreamHandlerで宣言されたメソッド

flush, isLoggable, setEncoding, setOutputStream

Java API 使用例 : StreamHandler」をご参照ください。

Handlerで宣言されたメソッド

getEncoding, getErrorManager, getFilter, getFormatter, getLevel, reportError, setErrorManager, setFilter, setFormatter, setLevel

Java API 使用例 : Handler」をご参照ください。


関連記事

ページの先頭へ