일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Docker
- Eclipse
- SpringBoot
- Open Source
- MySQL
- AJAX
- spring
- maven
- Core Java
- Source
- Tomcat
- jpa
- STS
- git
- 오픈소스
- MSSQL
- Thymeleaf
- Spring Boot
- Python
- JDBC
- 문서
- JavaScript
- ubuntu
- error
- 설정
- oracle
- myBatis
- PostgreSQL
- IntelliJ
- Exception
- Today
- Total
헤르메스 LIFE
[Log4j] Common-Logging의 문제점. 본문
원문 : 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에 대한 더 많은 궁금증은
에서 해결하실 수 있습니다.
'Spring Framework' 카테고리의 다른 글
[DataSource] org.apache.commons.dbcp.BasicDataSource 사용해서 DataSource 설정 (0) | 2012.05.31 |
---|---|
[MyBatis] ServletContextListener를 이용한 Application 시작 시 MyBatis 초기화 (0) | 2012.05.25 |
[Spring] ApplicationContext의 초기화 과정 (1) | 2012.05.22 |
[Spring] Spring + MyBatis 에서 여러 개의 Datasource Routing 하는 방법 (0) | 2012.05.21 |
[Spring] 스프링에서 현재 HttpServletRequest 가져오는 방법 (0) | 2012.04.12 |