2006/07
Log4jでフォーマットに(%F:%L)を指定すると(HogeServlet.java:75)
みたくログを出力したソースファイル名や行番号を出力してくれますが、
「なんでソースファイル名や行番号が分かるんだろう?」
「何かJVMの力を借りたりして裏技なのかなぁ?」
ということでLog4jのクラスを調べてみると
org.apache.log4j.spi.LocationInfoというクラスで
ソースファイル名、行番号等を取得しているようです。
やり方はといと
「例外のStackTraceを文字列解析してる」だけでした。
つまり、
「ソースファイル名、行番号等を取得するためだけにわざわざ例外を
newしてStackTraceを文字列解析してるわけです。」
なんの裏技でもないわけです。
「コンピュータの世界に魔法なんてないんだよね。」
JDK1.4からStackTraceを文字列解析しなくても簡単に情報を取得できる
「java.lang.StackTraceElement」というクラスがあります。今回はそれを使って
ログを出力したクラス名、メソッド名、ソースファイル名、行番号を出力する
シンプルなロガークラスを作成します。
package log; public class SimpleLogger { /** * ログを出力したクラス名、メソッド名、ソースファイル名、行番号、message * を出力する。 * @param message ログに出力するメッセージ */ public void debug(Object message) { /* * ログを出力したクラス名、メソッド名、ソースファイル名、行番号を * 取得するために例外をnewしてStackTraceElement[]を取得する。 */ StackTraceElement[] stackTrace = new Exception().getStackTrace(); // StackTraceElement[]の一番後ろの要素がログを出力したクラスの情報になる。 StackTraceElement info = stackTrace[stackTrace.length - 1]; // 出力内容を編集して標準出力に出力する。 System.out.println( info.getClassName() + "." + info.getMethodName() + "(" + info.getFileName() + ":" + info.getLineNumber() + ") " + message); } } package log; public class Main { public static void main(String[] args) { SimpleLogger log = new SimpleLogger(); log.debug("Hello SimpleLogger !!"); } }
[実行結果]
log.Main.main(Main.java:13) Hello SimpleLogger !!