プロジェクトでJavaのログライブラリとしてSLF4Jを使用していたけど、意識して使ってなかったので、意識的に動かしてみることにした。
SLF4Jとは
様々なロギングフレームワークを使用するためのシンプルなファサードまたは抽象化した機能を提供する。
SLF4Jを介して、ユーザがアプリケーションを実行する際に目的のロギングフレームワークを使用することが可能。
SLF4Jを使用することにより、ロギングフレームワークを変更することになった場合にソースコードに影響なくログイングフレームワークの変更のみで対応が可能。
具体的に言うとLogbackを使用していたけど、Log4j2にログライブラリを変更したいとなったときにSLF4Jを使用していれば、ソースコードを変更することなく、ログライブラリを変更することができる。
ロギングフレームワークの種類
Log4j2とは
Javaのロギングユーティリティ。Apacheから提供されている。 今は、Log4jの後継のLog4j2が主流。
Logbackとは
logbackはlog4jプロジェクトの後継プロジェクト。
既存のロギングシステムよりも高速に動作する。
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.xmlにlogback-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>
コンソールへの出力結果
サンプルソースを実行した際にコンソールに出力された結果は以下の通り。 定義したログレベルとメッセージフォーマットで出力されています。
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.xmlにlog4j-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>
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>
コンソールへの出力結果
サンプルソースを実行した際にコンソールに出力された結果は以下の通り。 定義したログレベルとメッセージフォーマットで出力されています。
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の活動が活発ではなくなってきているそうです。
まとめ
SLF4Jを使ったLogbackとLog4Jの動作確認を簡単にやってみました。
SLF4Jの概要知らずに使っていたのが恥ずかしい。
SLF4JとLobackの活動が活発出なくなってきたという記事を見つけたときは少し悲しくなりましたが、OSSだからしょうがないのだろうか。