SLF4J는 Apache commons-logging과 같이 SLF4J도 Facade 라이브러입니다.
그 말은 인터페이스만 있고, 해당 구현체는 별도의 라이브러리를 사용한다는 말입니다.
이에 대한 잇점은 시스템 전반적으로 사용되어진 로깅시스템의 교체가 수월해진다는 장점이 있습니다.
(사실 한번 적용된 로깅 시스템을 교체하는 경우는 특별한 경우가 아니고서야 별로 없긴 합니다.)
※ 하지만 SLF4J는 별도의 구현체 없이 단독으로도 사용가능하긴 합니다. ㅎ
SLF4J의 탄생 이유는 Aapche Commons-logging 의 비효율적인 문제들이라고 합니다.
여러가지가 있겠지만 잘 모르겠고..;; 개인적으로 편리한 기능 및 셈플 남겨봅니다.
logger.debug("param: " + param var); |
대부분 위와 같이 로그를 남길것이다.
하지만 운영의 DEBUG 하위 모드에서는 로그는 찍히지 않겠지만 로그 문자열에 대한 연산을 이루어져 그에 대한 비용이 발생한다고 합니다.
별거 아닌것 같지만 이에 대한 비용이 찝집하다네요 ㅎㅎ
if( logger.isDebugEnabled() ){ logger.debug("param: " + param var); } |
그래서 대부분 위와 같이 특정 로그레벨일 때만 처리 되도록 하긴 하지만 소스양이 늘어나고 귀찮아지죠.
그에 따라 위와 같이 하지 않고 첫번째 방법으로만 하는 경우가 파다합니다.
SLF4J는 이러한 비용을 절약되도록 설계되었다고 합니다.
logger.debug("param: {}", param var); |
위와 같이 문자열을 연산하지 않고, 해당 함수 내부에서 상황에 따라 연산이 이루어지게 하는것 같습니다.
[build.gradle]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | apply plugin: 'java' apply plugin: 'eclipse' sourceCompatibility = 1.6 repositories { mavenCentral() } // SLF4J 단독 List loggerSlf4j = [ "org.slf4j:slf4j-api:1.7.5" , "org.slf4j:slf4j-simple:1.7.5" , "org.slf4j:jcl-over-slf4j:1.7.5" ] // SLF4J + Log4j List loggerSlf4jAndLog4j = [ "org.slf4j:slf4j-log4j12:1.7.5" , "org.slf4j:jcl-over-slf4j:1.7.5" ] dependencies { //compile loggerSlf4j compile loggerSlf4jAndLog4j } // commons-logging 의존성 제거 configurations { all. collect { configuration -> configuration.exclude group: 'commons-logging' , module: 'commons-logging' } } |
[log4j.xml]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!--?xml version="1.0" encoding="UTF-8" ?--> < appender name = "STDOUT" class = "org.apache.log4j.ConsoleAppender" > < layout class = "org.apache.log4j.PatternLayout" > < param name = "ConversionPattern" value = "[%p] [%d{yyyy-MM-dd HH:mm:ss}] [%l][%c{1}][%L] %m %n" > </ layout > </ appender > < root > < priority value = "debug" > < appender-ref ref = "STDOUT" > </ appender-ref ></ priority ></ root > </ log4j:configuration > |
[Foo.java]
1 2 3 4 5 6 7 8 9 10 | import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Foo { static final Logger logger = LoggerFactory.getLogger(Foo. class ); public void doIt() { logger.debug( "안녕 {}" , "하세요." ); } } |
예제 소스에서 볼수 있듯이, SLF4J단독으로 사용하든, Log4j를 구현체로 사용하든 소스상에 변화는 없습니다.
설정 중 한가지 눈여겨볼 수항은 "jcl-over-slf4j" 입니다.
"jcl-over-slf4j' 추가 목적은 기존 Springfrawork 와 같이 Apache commons-logging를 사용하는 라이브러리를 사용하고 있을 경우 소스상은 commons-logging이지만 실제 동작은 SLF4J쪽을 호출 하도록 하는 역할을 하도록 합니다.
SLF4J + Log4j 에 대한 예제만 작성하였지만 "http://www.slf4j.org/manual.html" 사이트를 참고하시면 아래와 같이 각 구현체 마다 사용해야 하는 라이브러리 정보가 있습니다.
ch.qos.logback.classic.Logger
class is a direct implementation of SLF4J's org.slf4j.Logger
interface. Thus, using SLF4J in conjunction with logback involves strictly zero memory and computational overhead.