SLF4J 정리
in Java
SLF4J 는 실제 로깅을 수행하는 라이브러리가 아니라 다른 로깅 라이브러리(logj4j, logback)를 호출해서 로깅하는 중간 역할을 한다. 안써도 될 것 같은데 굳이 왜 쓰나?
뭐 딱히 그럴일은 없겠지만 요렇게 SLF4J의 org.slf4j.Logger를 사용했을 경우, 로깅 라이브러리를 변경하고 싶을때 기존 소스코드는 가만 냅두고 살짝 pom.xml 과 설정파일만 쫌 바꿔주면 쉽게 로깅 라이브러리를 교체할 수 있다.
요즘 log4j 가 업그레이드된 log4j2 가 뜬다고 함… 고럿다면 한번 써볼까 ‘ㅗ’? (예를들면 이런 경우?)
이것뿐 아니라 뭐 다른 이유도 많이 있겠지만…
package io.github.stove99.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Demo {
private static Logger log = LoggerFactory.getLogger(Demo.class);
public static void main(String[] args) {
log.debug("logging test : {}", "first log");
}
}
시작
위 샘플은 org.slf4j.Logger 이런 클래스가 없어서 컴파일이 되지 않는다. 컴파일 하기 위해 pom.xml 에 일단 slf4j 메인인 slf4j-api 를 추가한 다음 위 샘플을 실행해 보자
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
고러면 slf4j 가 사용할 실제 로깅 라이브러리가 없다면서 요런 에러가 난다.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
고럿다면 이제 쪽바로 작동할 수 있도록 실제 로깅 라이브러리를 설정해 보자.
첫번째로 고전적인 log4j 를 로깅 라이브러리로 설정해 보기
먼저 실제 로깅을 수행할 라이브러리인 log4j 를 pom.xml 에 추가한다.
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
딸랑 요렇게만 추가해 주면 끝나는게 아니라 slf4j 가 log4j 를 호출할 수 있도록 연결해 주는 라이브러리(slf4j binding)가 필요하다. 요 바인딩은 실제 로그를 수행할 로깅 라이브러리에 따라 다르기 때문에 맞춰서 설정해 주면 된다.
※ 당연한 이야기 지만 slf4j binding 라이브러리는 하나만 써야 된다. log4j 와 logback 을 동시에 쓸 수 없지 않은가?
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
</dependency>
요렇게 pom.xml 에 3가지 디펜던시를 추가하면 라이브러리 설정은 끝이고 log4j 설정 파일인 log4j.xml 파일을 classpath 루트에 폿 맹글어 준 다음 위 샘플을 실행하면 정상적으로 로그가 출력된다.
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="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %p [%c{5}] %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
logback 을 로깅 라이브러리로 설정해 보기
slf4j 로 logback 을 사용해서 로깅하도록 하는 설정은 매우 쉽다.
pom.xml 에 logback-classic 만 딸랑 하나 추가해 주면된다.
고러면 slf4j-api 와 실제 로깅 라이브러리인 logback-core, slf4j binding 역할을 하는 logback-classic 이 세가지 라이브러리가 클래스패스에 추가된다.
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
logback.xml
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<root level="debug">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
클래스패스 루트에 logback.xml 뽓 맨들어 준다음에 위 샘플을 실행해 보면 logback으로 출력되는 로그가 잘 찍힌다.
고러면 xxx-over-slf4 는 무엇임?
jcl-over-slf4j, log4j-over-slf4j 요런거를 pom.xml 파일에서 자주 볼 것이다.
죠것들은 기존 소스파일에서 org.apache.log4j.Logger 요렇게 사용하고 있던걸 소스 수정없이 slf4j 로 연결해 주기 위한 라이브러리 시리즈이다.
import org.apache.log4j.Logger;
private static Logger logger = Logger.getLogger(Main.class.getName());
내가 관리하는 소스야 싹 찾아서 slf4j 로 바꿔주면 되는데 가져다 쓰는 다른 라이브러리에서 log4j 를 사용해서 로깅처리를 하고 있다면 살짝 곤란해 진다. 고런 문제를 해결해주는 것이 xxx-over-slf4j 시리즈임.