ヒトリ歩き

愚痴とかいろいろ書きます

今更、SLF4Jを意識してみた

f:id:kotapontan:20210822195505p:plain プロジェクトでJavaのログライブラリとしてSLF4Jを使用していたけど、意識して使ってなかったので、意識的に動かしてみることにした。

SLF4Jとは

様々なロギングフレームワークを使用するためのシンプルなファサードまたは抽象化した機能を提供する。
SLF4Jを介して、ユーザがアプリケーションを実行する際に目的のロギングフレームワークを使用することが可能。 SLF4Jを使用することにより、ロギングフレームワークを変更することになった場合にソースコードに影響なくログイングフレームワークの変更のみで対応が可能。

具体的に言うとLogbackを使用していたけど、Log4j2にログライブラリを変更したいとなったときにSLF4Jを使用していれば、ソースコードを変更することなく、ログライブラリを変更することができる。

ロギングフレームワークの種類

Log4j2とは

Javaのロギングユーティリティ。Apacheから提供されている。 今は、Log4jの後継のLog4j2が主流。

Logbackとは

logbacklog4jプロジェクトの後継プロジェクト。
既存のロギングシステムよりも高速に動作する。

loggingとは

JREに含まれているロギング機能。

SLF4Jを使ってLogbackとLog4j2を使ってみる

コンソールに出力するレベルでSLF4Jを経由してLogbackとLog4j2を使用してみる。
使用するソースは以下のソースを使用するTRACE〜ERRORレベルの簡単なメッセージを実装したソースコードを使用する。

package jp.slf4j.sample.slf4j;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {

    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(HelloWorld.class);

        logger.trace("TRACE!!");
        logger.debug("DEBUG!!");
        logger.info("INFO!!");
        logger.warn("WARN!!");
        logger.error("ERROR!!");

    }
}

Logback

pom.xmlの定義

Logbackを使用する場合はpom.xmllogback-classicの定義が必要です。 logback-classicを定義すれば、依存関係でslf4j-apiもダウンロードしてくれるが、最新のslf4j-apiではないため、ここではslf4j-apiの1.7.32を定義しておきます。

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.3</version>
</dependency>

logback.xmlの定義

logback.xmlをクラスパスが通っているディレクトリに配置します。
定義の内容はコンソールに出力する程度の定義に留めています。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE logback>
<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] logback! %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="info">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

logback.qos.ch

コンソールへの出力結果

サンプルソースを実行した際にコンソールに出力された結果は以下の通り。 定義したログレベルとメッセージフォーマットで出力されています。

2021-08-17 22:55:07.855 [main] logback! INFO  jp.slf4j.sample.slf4j.HelloWorld - INFO!!
2021-08-17 22:55:07.858 [main] logback! WARN  jp.slf4j.sample.slf4j.HelloWorld - WARN!!
2021-08-17 22:55:07.858 [main] logback! ERROR jp.slf4j.sample.slf4j.HelloWorld - ERROR!!

Log4j2

pom.xmlの定義

Log4j2を使用する場合は、pom.xmllog4j-slf4j-implを定義する必要あります。
Logbackと同様にlog4j-slf4j-implだけを定義すればslf4j-apiの依存関係でダウンロードしてきてくれますが、slf4j-apiの最新バージョンを使用するために定義をしておきます。

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.14.1</version>
</dependency>

logging.apache.org

log4j2.xmlの定義

log4j2.xmlファイルをクラスパスが通っているディレクトリに配置します。
Logbackと同様にコンソールにメッセージを出力する程度の定義としています。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYY-MM-dd HH:mm:ss.SSS} log4j2 [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

logging.apache.org

コンソールへの出力結果

サンプルソースを実行した際にコンソールに出力された結果は以下の通り。 定義したログレベルとメッセージフォーマットで出力されています。

2021-08-17 22:45:24.955 log4j2 [main] TRACE jp.slf4j.sample.slf4j.HelloWorld - TRACE!!
2021-08-17 22:45:24.957 log4j2 [main] DEBUG jp.slf4j.sample.slf4j.HelloWorld - DEBUG!!
2021-08-17 22:45:24.957 log4j2 [main] INFO  jp.slf4j.sample.slf4j.HelloWorld - INFO!!
2021-08-17 22:45:24.958 log4j2 [main] WARN  jp.slf4j.sample.slf4j.HelloWorld - WARN!!
2021-08-17 22:45:24.958 log4j2 [main] ERROR jp.slf4j.sample.slf4j.HelloWorld - ERROR!!

SLF4JとLogbackの活動が活発ではない。

実務のプロジェクトではLog4j2ではなく、Logbackが採用されていました。
ただ、SLF4JやLogbackの活動が活発ではなくなってきているそうです。

blog.kengo-toda.jp

まとめ

SLF4Jを使ったLogbackLog4Jの動作確認を簡単にやってみました。
SLF4Jの概要知らずに使っていたのが恥ずかしい。
SLF4JとLobackの活動が活発出なくなってきたという記事を見つけたときは少し悲しくなりましたが、OSSからしょうがないのだろうか。