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
「Loggerにハンドラを追加してみる」にて示された、サンプルソースでは、「setLevel(Level.ALL);」が記載されていますが、これは「setLevel(Level.INFO);」の間違いでは?
当時のことは何も覚えていませんが、話の流れからはLevel.ALLで合っているように思いました。<br>LoggerにALLを設定しても、ハンドラがデフォルトでINFOレベルにフィルタリングするということなのだと思います。その後でハンドラに明示的にALLを設定すると全部のログレベルの出力を得られているので。