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

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


概要

クラス構成

Handlerクラスは、ログをどこに出力するのか?を決める抽象クラスです。
例えば、サブクラスのConsoleHandlerはコンソールに、FileHandlerはファイルにログを出力します。

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

コンストラクタ

Handler ()

デフォルトのコンストラクタです。

※独自のHandlerを作るときに使います。

class SampleHandler extends Handler {
    @Override
    public void publish(LogRecord record) {
        // 必要な処理を実装
    }

    @Override
    public void flush() {
        // 必要な処理を実装
    }

    @Override
    public void close() throws SecurityException {
        // 必要な処理を実装
    }
}

final Handler handler = new SampleHandler();

System.out.println(handler.getLevel()); // ALL
System.out.println(handler.getFilter()); // null
System.out.println(handler.getFormatter()); // null

メソッド

abstract void close ()

Handlerを閉じて、関連するすべてのリソースを解放します。

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

final Handler 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.println(Files.readString(pattern));

// 結果
// ↓
//<?xml version="1.0" encoding="UTF-8" standalone="no"?>
//<!DOCTYPE log SYSTEM "logger.dtd">
//<log>
//<record>
//  <date>2022-03-13T10:43:28.380133800Z</date>
//  <millis>1647168208380</millis>
//  <nanos>133800</nanos>
//  <sequence>1</sequence>
//  <logger>com.example.logging</logger>
//  <level>INFO</level>
//  <class>com.example.logging.HandlerTest$1</class>
//  <method>method</method>
//  <thread>1</thread>
//  <message>TEST LOG!</message>
//</record>
//</log>

abstract void flush ()

バッファリングされた出力をフラッシュします。

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

final var outputStream = new ByteArrayOutputStream();

// flushの効果が分かりやすいように StreamHandler を使います。
final Handler handler = new StreamHandler(outputStream, new SimpleFormatter());

logger.addHandler(handler);

logger.info("TEST LOG!");

System.out.println("-- before flush --");
System.out.println(outputStream);

handler.flush();

System.out.println("-- after flush --");
System.out.println(outputStream);

// 結果
// ↓
//-- before flush --
//
//-- after flush --
//3月 13, 2022 5:34:25 午後 com.example.logging.HandlerTest$2 method
//情報: TEST LOG!

String getEncoding ()

このHandlerの文字エンコーディングを返します。

System.out.println(Charset.defaultCharset()); // UTF-8

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

final Handler handler = new ConsoleHandler();
System.out.println(handler.getEncoding()); // null
logger.addHandler(handler);

logger.info("TEST LOG : 〇△□×");

// UTF-8用のコンソールへ出力する例です。

// 結果
// ↓
//3月 13, 2022 7:55:02 午後 com.example.logging.HandlerTest$3 method
//情報: TEST LOG : 〇△□×

handler.setEncoding("Shift_JIS");
System.out.println(handler.getEncoding()); // Shift_JIS

logger.info("TEST LOG : 〇△□×");

// 結果 (SJIS用のコンソールではないので文字化けします)
// ↓
//3�� 13, 2022 7:55:02 �ߌ� com.example.logging.HandlerTest$3 method
//���: TEST LOG : �Z�����~

ErrorManager getErrorManager ()

このHandlerのErrorManagerを取得します。

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

final Handler handler = new ConsoleHandler() {
    @Override
    public void publish(LogRecord record) {
        // 意図的に例外をレポートします。
        reportError("TEST ERROR!",
                new IllegalStateException("TEST EXCEPTION!"), 
                ErrorManager.GENERIC_FAILURE);
    }
};

logger.addHandler(handler);

class CustomErrorManager extends ErrorManager {
    @Override
    public synchronized void error(String msg, Exception ex, int code) {
        System.err.println("CUSTOM ERROR! : " + msg + " : " + ex.getMessage());
    }
}

// デフォルトのErrorManager
System.out.println(handler.getErrorManager() instanceof CustomErrorManager); // false

logger.info("TEST LOG!");

// 結果
// ↓
//java.util.logging.ErrorManager: 0: TEST ERROR!
//java.lang.IllegalStateException: TEST EXCEPTION!
//	at com.example.logging.HandlerTest$6$1.publish(HandlerTest.java:354)
//...

// カスタムしたErrorManager
handler.setErrorManager(new CustomErrorManager());
System.out.println(handler.getErrorManager() instanceof CustomErrorManager); // true

logger.info("TEST LOG!");

// 結果
// ↓
//CUSTOM ERROR! : TEST ERROR! : TEST EXCEPTION!

Filter getFilter ()

このHandlerの現在のFilterを取得します。

final Handler handler = new ConsoleHandler();

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

System.out.println(handler.getFilter()); // null

logger.info("abcd");
logger.info("EFG");
logger.info("xyz");

// 結果 (フィルタなし)
// ↓
//3月 13, 2022 8:03:08 午後 com.example.logging.HandlerTest$4 method
//情報: abcd
//3月 13, 2022 8:03:08 午後 com.example.logging.HandlerTest$4 method
//情報: EFG
//3月 13, 2022 8:03:08 午後 com.example.logging.HandlerTest$4 method
//情報: xyz

final var filter = new Filter() {
    @Override
    public boolean isLoggable(LogRecord record) {
        // 小文字のみを対象とします。
        final var msg = record.getMessage();
        return msg.equals(msg.toLowerCase());
    }
};

handler.setFilter(filter);
System.out.println(filter == handler.getFilter()); // true

logger.info("abcd");
logger.info("EFG");
logger.info("xyz");

// 結果 (フィルタあり)
// ↓
//3月 13, 2022 8:04:04 午後 com.example.logging.HandlerTest$4 method
//情報: abcd
//3月 13, 2022 8:04:04 午後 com.example.logging.HandlerTest$4 method
//情報: xyz

Formatter getFormatter ()

このHandlerのFormatterを返します。

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

// ConsoleHandlerのデフォルトはSimpleFormatter
final Handler handler = new ConsoleHandler();
logger.addHandler(handler);

// java.util.logging.SimpleFormatter@6a8658ff
System.out.println(handler.getFormatter());

logger.info("TEST LOG!");

// 結果
// ↓
//3月 13, 2022 6:35:17 午後 com.example.logging.HandlerTest$5 method
//情報: TEST LOG!

handler.setFormatter(new XMLFormatter());

// java.util.logging.XMLFormatter@491b9b8
System.out.println(handler.getFormatter());

logger.info("TEST LOG!");

// 結果
// ↓
//<record>
//  <date>2022-03-13T09:35:17.399239800Z</date>
//  <millis>1647164117399</millis>
//  <nanos>239800</nanos>
//  <sequence>2</sequence>
//  <logger>com.example.logging</logger>
//  <level>INFO</level>
//  <class>com.example.logging.HandlerTest$5</class>
//  <method>method</method>
//  <thread>1</thread>
//  <message>TEST LOG!</message>
//</record>

Level getLevel ()

このHandlerがどのメッセージをロギングするかを指定するログ・レベルを取得します。

final var logger = Logger.getLogger("com.example.logging");
logger.setUseParentHandlers(false);
logger.setLevel(Level.ALL);

final Handler handler = new ConsoleHandler();
logger.addHandler(handler);

// ConsoleHandlerのデフォルトレベルはINFO
System.out.println(handler.getLevel()); // INFO

logger.warning("WARNING LOG!");
logger.info("INFO LOG!");
logger.fine("FINE LOG!");
logger.finer("FINER LOG!");

// 結果
// ↓
//3月 13, 2022 7:28:11 午後 com.example.logging.HandlerTest$7 method
//警告: WARNING LOG!
//3月 13, 2022 7:28:11 午後 com.example.logging.HandlerTest$7 method
//情報: INFO LOG!

handler.setLevel(Level.FINE);
System.out.println(handler.getLevel()); // FINE

logger.warning("WARNING LOG!");
logger.info("INFO LOG!");
logger.fine("FINE LOG!");
logger.finer("FINER LOG!");

// 結果
// ↓
//3月 13, 2022 7:28:11 午後 com.example.logging.HandlerTest$7 method
//警告: WARNING LOG!
//3月 13, 2022 7:28:11 午後 com.example.logging.HandlerTest$7 method
//情報: INFO LOG!
//3月 13, 2022 7:28:11 午後 com.example.logging.HandlerTest$7 method
//普通: FINE LOG!

boolean isLoggable (LogRecord record)

このHandlerが、指定されたLogRecordを実際にロギングするかどうかを調べます。

final Handler handler = new ConsoleHandler();
System.out.println(handler.getLevel()); // INFO

final var ret1 = handler.isLoggable(new LogRecord(Level.WARNING, "WARNING!"));
System.out.println(ret1); // true

final var ret2 = handler.isLoggable(new LogRecord(Level.INFO, "INFO!"));
System.out.println(ret2); // true

final var ret3 = handler.isLoggable(new LogRecord(Level.FINE, "FINE!"));
System.out.println(ret3); // false

final var ret4 = handler.isLoggable(new LogRecord(Level.FINER, "FINER!"));
System.out.println(ret4); // false

abstract void publish (LogRecord record)

LogRecordを発行します。

getErrorManager()の使用例に publish もまとめて記載しました。
API使用例はそちらをご参照ください。

protected void reportError (String msg, Exception ex, int code)

このHandlerのErrorManagerにエラーを通知する簡易protected簡易メソッドです。

getErrorManager()の使用例に reportError もまとめて記載しました。
API使用例はそちらをご参照ください。

void setEncoding (String encoding)

このHandlerが使用する文字エンコーディングを設定します。

getEncoding()の使用例に setEncoding もまとめて記載しました。
API使用例はそちらをご参照ください。

void setErrorManager (ErrorManager em)

このHandlerのErrorManagerを定義します。

getErrorManager()の使用例に setErrorManager もまとめて記載しました。
API使用例はそちらをご参照ください。

void setFilter (Filter newFilter)

このHandlerの出力を制御するFilterを設定します。

getFilter()の使用例に setFilter もまとめて記載しました。
API使用例はそちらをご参照ください。

void setFormatter (Formatter newFormatter)

Formatterを設定します。

getFormatter()の使用例に setFormatter もまとめて記載しました。
API使用例はそちらをご参照ください。

void setLevel (Level newLevel)

このHandlerがどのメッセージ・レベルをロギングするかを指定するログ・レベルを設定します。

getLevel()の使用例に setLevel もまとめて記載しました。
API使用例はそちらをご参照ください。


関連記事

ページの先頭へ