文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

皆間違うlog.error(e);はStackTraceが出ないので要注意!

javaのロガーのお話です。


f:id:treeapps:20180426142529p:plain

commons-loggingの話ですが、どうも勘違いしている人が多いのです。

log.error(e); でStackTraceは出力されませんよ!!

あまりにも勘違いしている人が多いように見えます。

よく見るStackTraceが出そうで出ない例

	try {
		
	} catch (Exception e) {
		log.error(e);
	}

正しくStackTraceが出力されるコード

	try {
		
	} catch (Exception e) {
		log.error(e.getMessage(), e);
	}

何故こうなる?

commons-loggingのメソッドのjavadocを良く見ましょう。

    /**
     * <p> Log a message with error log level. </p>
     *
     * @param message log this message
     */
    public void error(Object message);


    /**
     * <p> Log an error with error log level. </p>
     *
     * @param message log this message
     * @param t log this cause
     */
    public void error(Object message, Throwable t);

messageって書いてありますよ!Throwableじゃないですよ!

Object型なのでThrowableも受け付けてしまいます

内部の処理までは追ってませんが、引数1個のメソッドの方は、単にメッセージを出力する処理しかしてないはずなので、eを渡してもeがtoString()されたものがログ出力されているのでしょう。
だから1行だけエラーログが出て、StackTraceが出ないのです。

従って、エラー時は

log.error(e.getMessage(), e);

のようにした方がよいです。e.getMessage()は任意の文字列を設定した方がいいですね。

jenkinsでlog.error(e)を検出する

Task Scanner Plugin を使って機械的に検出させるといいかもしれませんね。
他にも、System.out.printlnとかも邪悪なので、合わせて検出しておきたいところです。
Task Scanner Plugin - Jenkins - Jenkins Wiki

ロガーを正しく学ぶ

そもそもjavaのロガーは大変種類が多く、interfaceと実装が分かれていて非常にカオスになっています。
そのあたりを解りやすく開設した記事を書いたので、合わせてご覧下さい!
javaのロガーが多すぎて訳が解らないので整理してみました - 文系プログラマによるTIPSブログ