SLF4J+Lobackの基本

SLF4JとLogbackの基本をおさえる。

SLF4JとLogbackの基本をおさえる。

SLF4Jがインターフェース、Logbackが実装

ロギング用のライブラリは乱立傾向にあり柔軟に対応するため、インターフェース用のライブラリと実装用のライブラリを分離されている。SLF4JとLogbackも分かれて提供されている。

Logbackだけでもロギング可能だが、SLF4Jも使うようにする。コードが別プロジェクトから依存される場合にロギング実装ライブラリが違うと面倒なことになる。なので、コード上はSLF4J(インターフェース)に対してプログラミングしておく。そうすれば設定の変更などでロギング実装ライブラリの違いをなんとか吸収できる可能性がある。

SLF4JとLogbackの組合せ以外にもいくつかのライブラリの組合せが考えられるが、LogbackはSLF4Jのネイティブ実装にあたるため、この組合せでいい。

jarの構成

いろいろな状況に対応するため、(特にSLF4J側は)jarファイルが分割されている。この図(https://www.slf4j.org/images/concrete-bindings.png)を見ると必要なjarの組合せがわかる。SLF4JとLogbackのみであれば複雑ではない。

ただ依存しているライブラリが他のロギングライブラリを使用しているかつそのログを見なければいけない場合は、この図等を参考にしてjarの構成を修正する。

SLF4JとLogbackのみ場合

「slf4j-api」「logback-core」「logback-classic」が必要になるが「logback-classic」が他に依存しているため、Mavenであれば「logback-classic」だけ書けばいい。

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.versio}</version>
</dependency>

Spring bootの場合

「spring-boot-starter」がlogbackに依存しているため、特にjarを追加しなくも使える。

使い方

Loggerを取得して、ログ出力をするだけ。

Loggerの取得

LoggerFactoryに「クラス」or「名前」を指定することで取得できる。

基本的には自分のクラスを引数に渡す形で取得する。自分のクラス名の絶対名でロガーを取得することになり、logback.xmlによるログ出力のフィルタリングを行いやすくなる。パッケージ名やクラス名でそのままフィルタリング設定が可能になる。それ以外に特別なロギングをしたい場合は、直接名前を指定してあげればよい。

クラスを引数に渡す場合
public class LogOutputTest {
    private static final Logger log = LoggerFactory.getLogger(LogOutputTest.class);
}
名前を引数に渡す場合
public class MyNameLoggerTest {
    private static final Logger log = LoggerFactory.getLogger("mylogger.debug");
}

ただ、これを毎回書くのはしんどいのでLombokなどをつかった方がいい。@slf4jでクラスを引数に渡す場合のロガーを取得している状態となる。

Lombokによるロガーの取得
@slf4j
public class LogOutputTest {
}

ログの出力

Loggerのそれぞれのメソッドは、ログレベルに対応している。また、例外を受け取るメソッドも用意されていて、その場合スタックトレースがログに出力される。

ログの出力の例
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogOutputTest {
    private static final Logger log = LoggerFactory.getLogger(LogOutputTest.class);

    @Test public void test_outputLog() throws Exception {
        log.trace("traceです。");
        log.debug("debugです。");
        log.info("infoです。");
        log.warn("warnです。");
        log.error("errorです。");

        try {
            // 何らかの処理
        } catch (Exception e) {
            log.warn("○○で例外発生です。", e);
        }
    }
}

ログメッセージに{}を記述すると プレースフォルダー として利用できる。

プレースホルダー利用例
int number01 = 1234;
int number02 = 5678;
log.debug("この数値は{}と{}です。", number01, number02);
出力
20:00:33 DEBUG - この数値は1234と5678です。