157
142

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

アルス・ウェアーAdvent Calendar 2018

Day 7

SLF4J、Logback、Log4Jの関係を挙動とともに整理する

Last updated at Posted at 2018-12-06

SLF4J、Logback、Log4Jの違いや関係を挙動とともに整理してみます。

SLF4Jとは

Javaのロギング実装の柔軟な切り替えを実現するFacadeのことをSLF4Jといいます。
SLF4J
Facade(ファサード)とは「建物の正面」を意味していて、GoFのデザインパターンの1つ「Facadeパターン」のことを指します。以下はFacadeパターンのクラス図です(TECHSCOREより)。
facade2.gif

Javaのロギング実装には、Log4JやLog4J 2、Logback等がありますが、これらの実装の窓口となるのがSLF4Jです。上記図では、FacadeがSLF4J、classAがLog4J、classBがLogbackなイメージです。

公式にある以下の図がイメージしやすいかと思います。
concrete-bindings.png
つまり、アプリケーションから見るとSLF4Jはロギング実装のインターフェースの役割を担い、Logback、Log4Jはロギング実装そのものになります。

SLF4Jの威力

SLF4Jの威力、と言いつつもFacadeパターン(突き詰めるとインターフェースの威力)になるのですが、SLF4Jを利用することでどんなメリットがあるかを以下のコードで確認してみます。

App.java
public class App {
	public static void main(String[] args) {
		Logger logger = LoggerFactory.getLogger(App.class);
		logger.info("INFO LOG!!  Logger Class=" + logger.getClass());
	}
}

ロギング実装にLogbackを使う

まずは、ロギング実装にLogbackを使ってみます。Logbackを使うためにpom.xmlに以下の通り依存関係を追加します。

pom.xml
// Logbackの場合、この追加だけでMavenの推移的依存関係により、SLF4J(slf4j-api)とlogback-coreも依存関係に追加されます。
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
	<version>1.2.3</version>
</dependency>

ビルドしApp.javaを実行してみます。すると、コンソールに以下が出力されます。

Console.
23:53:02.124 [main] INFO co.jp.ars.App - INFO LOG!!  Logger Class=class ch.qos.logback.classic.Logger

「Logger Class=class ch.qos.logback.classic.Logger」とあるように、ロギング実装にLogbackが使われていることが確認できます。

ロギング実装にLog4Jを使う

次に、ロギング実装にLog4Jを使ってみます。Log4Jを使うためにpom.xmlに以下の通り依存関係を追加します。

pom.xml
// Log4Jの場合、この追加だけでMavenの推移的依存関係により、log4j-x.x.x.jarも依存関係に追加されます。
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.25</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-log4j12</artifactId>
	<version>1.7.25</version>
</dependency>

Log4Jを使う場合、log4j.xml(もしくはlog4j.properties)が必要なので、クラスパス上に以下の通りlog4j.xmlを作成します。

log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
	<appender name="demo" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%t %-5p %c{2} - %m%n" />
		</layout>
	</appender>
	<logger name="co.jp.ars">
		<level value="info" />
		<appender-ref ref="demo" />
	</logger>
</log4j:configuration>

ビルドしApp.javaを実行してみます。すると、コンソールに以下が出力されます。

Console.
main INFO  ars.App - INFO LOG!!  Logger Class=class org.slf4j.impl.Log4jLoggerAdapter

「Logger Class=class org.slf4j.impl.Log4jLoggerAdapter」とありますが、Log4jLoggerAdapterの実装は以下の通りとなっており、Loggerの実態は「org.apache.log4j.Logger」になっていることが確認できます(つまりロギング実装にLog4Jが使われていることが確認できます)。

Log4jLoggerAdapter.java
public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger, Serializable {

    private static final long serialVersionUID = 6182834493563598289L;

    final transient org.apache.log4j.Logger logger;

    // ~省略~

    public void info(String msg) {
        logger.log(FQCN, Level.INFO, msg, null);
    }

    // ~省略~
}

SLF4J + Log4Jの場合、両者の間にSLF4Jバインディングと呼ばれる中間アダプターが入ります。その中間アダプターが上記の「Log4jLoggerAdapter 」になります。以下再掲です。
concrete-bindings.png

何が嬉しいのか?

ロギング実装を設定で切り替えただけで、ログ出力を行っているアプリ(App.java)には一切手を加えていません。冒頭で「Javaのロギング実装の柔軟な切り替えを実現するFacadeのことをSLF4Jといいます」と述べましたが、SLF4JというFacadeを使うことでロギング実装を柔軟に切り替えることが可能となります。

Logback、Log4jのトレンド

ちなみに、ロギング実装のトレンド的にはさほど変わりはありません(2018/12/6時点)
キャプチャ.PNG

以上です。

参考

157
142
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
157
142

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?