メモの日々


2013年08月26日(月) [長年日記]

[java] java.util.logging.Logger でログを出す

java.util.logging.Loggerを使おうとするといつも躓くのでメモ。

getGlobal()で取得できるグローバルロガーを使ってみる。使用したJavaのバージョンは 1.7.0_25。

何も設定しないと何も出力されない

次のプログラムは何も出力しない。

import java.util.logging.Logger;

public class LogTest {
    public static void main(String[] args) {
        Logger.getGlobal().severe("severe");
        Logger.getGlobal().info("info");
        Logger.getGlobal().config("config");
        Logger.getGlobal().finest("finest");
    }
}

setLevel(Level.ALL)を呼んでみる

Loggerオブジェクトに対しsetLevel(Level.ALL)を呼ぶようにする

import java.util.logging.Level;
import java.util.logging.Logger;

public class LogTest {
    public static void main(String[] args) {
        Logger.getGlobal().setLevel(Level.ALL); // <---
        Logger.getGlobal().severe("severe");
        Logger.getGlobal().info("info");
        Logger.getGlobal().config("config");
        Logger.getGlobal().finest("finest");
    }
}

と、INFOレベル以上のログだけが標準エラーに出力されるようになる。

8 26, 2013 7:35:14 午後 LogTest main
SEVERE: severe
8 26, 2013 7:35:14 午後 LogTest main
情報: info

こうなるのは、「デフォルトの構成では、ルートロガーのハンドラの 1 つがコンソールへの出力用として設定」されているからのようだ。

setUseParentHandlers(false) を呼んでみる

Loggerオブジェクトに対しsetUseParentHandlers(false)を呼ぶようにすると、再び何も出力されなくなる。ログがルートロガーへ送られなくなるからだろう。

import java.util.logging.Level;
import java.util.logging.Logger;

public class LogTest {
    public static void main(String[] args) {
        Logger.getGlobal().setUseParentHandlers(false); // <---
        Logger.getGlobal().setLevel(Level.ALL);
        Logger.getGlobal().severe("severe");
        Logger.getGlobal().info("info");
        Logger.getGlobal().config("config");
        Logger.getGlobal().finest("finest");
    }
}

Loggerにハンドラを追加してみる

LoggerオブジェクトのaddHandler()を呼んでハンドラを追加する

import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.StreamHandler;

public class LogTest {
    public static void main(String[] args) {
        Logger.getGlobal().setUseParentHandlers(false);
        Logger.getGlobal().setLevel(Level.ALL);
        Logger.getGlobal().addHandler(new StreamHandler() {{ // <---
            setOutputStream(System.out);
        }});
        Logger.getGlobal().severe("severe");
        Logger.getGlobal().info("info");
        Logger.getGlobal().config("config");
        Logger.getGlobal().finest("finest");
    }
}

と、INFOレベル以上のログだけが(上の例だと標準出力に)出力されるようになる。

8 26, 2013 7:59:46 午後 LogTest main
SEVERE: severe
8 26, 2013 7:59:46 午後 LogTest main
情報: info

ハンドラに対しsetLevel(Level.ALL)を呼んでみる

ハンドラに対してもsetLevel(Level.ALL)を呼ぶようにする

import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.StreamHandler;

public class LogTest {
    public static void main(String[] args) {
        Logger.getGlobal().setUseParentHandlers(false);
        Logger.getGlobal().setLevel(Level.ALL);
        Logger.getGlobal().addHandler(new StreamHandler() {{
            setOutputStream(System.out);
            setLevel(Level.ALL); // <---
        }});
        Logger.getGlobal().severe("severe");
        Logger.getGlobal().info("info");
        Logger.getGlobal().config("config");
        Logger.getGlobal().finest("finest");
    }
}

と、全部のログが出力された。

8 26, 2013 8:05:55 午後 LogTest main
SEVERE: severe
8 26, 2013 8:05:55 午後 LogTest main
情報: info
8 26, 2013 8:05:55 午後 LogTest main
CONFIG: config
8 26, 2013 8:05:55 午後 LogTest main
FINEST: finest
本日のツッコミ(全2件) [ツッコミを入れる]
伊藤史朗 (2022年09月12日(月) 17:21)

「Loggerにハンドラを追加してみる」にて示された、サンプルソースでは、「setLevel(Level.ALL);」が記載されていますが、これは「setLevel(Level.INFO);」の間違いでは?

小川 (2022年09月12日(月) 18:10)

当時のことは何も覚えていませんが、話の流れからはLevel.ALLで合っているように思いました。<br>LoggerにALLを設定しても、ハンドラがデフォルトでINFOレベルにフィルタリングするということなのだと思います。その後でハンドラに明示的にALLを設定すると全部のログレベルの出力を得られているので。