헤르메스 LIFE

[Log4j] Common-Logging의 문제점. 본문

Spring Framework

[Log4j] Common-Logging의 문제점.

헤르메스의날개 2012. 5. 22. 17:56
728x90

원문 : http://chanwook.tistory.com/727


SLF4J는 commons-loggin이 갖는 몇 가지 문제점(이 글에서 다룬 문제+클래스 로딩 문제 등)을 해결하면서 등장한 로깅 API입니다.

commons-loggin을 활용하는 방법은 간단하죠^^.

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

이 예는 DEBUG 수준의 로그를 남기게 됩니다. 하지만 이렇게 작성하면 큰 문제를 일으킵니다. 일반적으로 DEBUG 수준의 로그는 개발시나 디버깅 시에만 남기는데, 이렇게 코드를 해놓으면 로깅 수준에 관계 없이 항상 debug() 파라미터로 넘기는 문자열을 구성하게 됩니다.

위 예에서는 i와 String.valueOf(entry[i])라는 두 개의 파라미터를 받는데, 이 두 개의 인자를 처리해서 완성된 문자열로 만드는 작업에 드는 비용이 만만치 않습니다. 자바에서 String 처리는 상당한 비용을 사용하게 되죠.. 

이런 문제를 해결하는 방법으로 다음처럼 코드를 작성하게 됩니다.

if(logger.isDebugEnabled()) { 
    logger.debug("Entry number: " + i + " is " + String.valueOf(entry
[i])); 
}

실제로 로깅 메소드를 호출하기 전에, 해당 수준의 로깅을 해야할지 여부를 먼저 따져보게 됩니다. 그래서 로깅이 필요하면 남기고, 필요 없으면 남기지 않게 됩니다.

이렇게 하면 로깅을 하지 않아도 될 때는 파라미터를 구성하면서 문자열을 처리할 필요가 없게 됩니다. isDebugEnabled() 자체도 수행되는데 무시할 정도의 시간밖에 걸리지 않습니다.

하지만 그럼에도 아쉬운 점이 있습니다. 로깅을 하지 않아도 될 때는 isDebugEnabled()만 거치면 되지만, 실제 로깅을 남겨야 할 때는 isDebugEnabled() -> debug() 로 두 개의 메소드 호출이 일어 납니다.(아무리 작은 시간이 소모되더라도요..) 

그리고 제가 생각하는 더 안 좋은 점은 코드가 상당히 껄끄러워 집니다. DEBUG와 INFO, WARN 수준의 로그를 연달아 남기고, DEBUG가 여러번 겹쳐서 나오기라도 하면 아주 정신이 다 없어 집니다@@.

SLF4J는 별도의 파라미터 포매팅 개념을 도입했습니다! 이른바 Parameterized loggin method.

코드를 보시면, 

Object entry = new SomeObject(); 
logger.debug("The entry is {}.", entry);

인자로 넘기는 코드는 없다치면, 실제로 로그를 남기는 코드만 남게 됩니다. isXXXEnabled() 메소드가 없어졌습니다. 대신 이른바 Formatting anchor로 불리는 '{}'가 등장했습니다. SLF4J는 로깅을 남겨야할 필요가 있을 때 {}를 메소드의 파라미터로 받은 값으로 교체하게 됩니다. 로깅을 남길 필요가 없는 상황에서는 문자열을 구성하지 않는 것이지요^^. 

여기서 로깅을 남겨야하는 여부를 결정하는 행위의 주체가 SLF4J로 넘어가게 됐습니다.

commons-loggin: logger.debug("The new entry is "+entry+"."); 
SLF4J: logger.debug("The new entry is {}.", entry);

이 두 로깅 코드는 거의 동일한 코드고, 완전 같은 로그 메세지를 남기지만, 성능은 30배 정도의 차이가 나게 됩니다. SLF4J는 별도의 파라미터 포매팅 구현을 사용합니다. 일반 포매팅 방법보다 10배 정도 빠르다고 합니다. 그래서 {}를 메소드 인자로 매핑하는데 크게 부하가 걸리지 않는다고 하네요..

SLF4J를 적용하면 바로 로깅 메소드를 호출해도 됩니다.^^

OSGi 환경에서는 클래스 로딩 문제로 commons-loggin 대신에 SLF4J를 사용하는데 그것 말고도 다양한 장점이 있네요. 많은 오픈소스들이 commons-loggin과 결별을 고하고, SLF4J로 

갈아타고 있습니다



함께 동참하시겠어요^^.

SLF4J에 대한 더 많은 궁금증은 

FAQ

에서 해결하실 수 있습니다.

728x90