# log4j slf4j logback log4j 뭘 써야 하지?
이 소스 저 소스 보다 보면 여러 로그 라이브러리를 보게 된다. 어떤 것이 제일 좋을까? maven이나 gradle에 로그 라이브러리를 추가할때 왜 여러 로그를 설정하는 걸까? 그 놈이 그 놈아닌가? 이 참에 정리해 보자.
# Legacy Logging Libraries
# java.util.logging(JUL)
- 언어차원에서 지원하는 로거
- java 1.4버전(2002년) 부터 지원
java.util.logging.Logger logger = java.util.logging.Logger.getLogger(this.getClass().getName());
logger.info("This is an info message");
logger.severe("This is an error message"); // ERROR
logger.fine("Here is a debug message"); // DEBUG
1
2
3
4
2
3
4
- server와 find은 생소해 보이지만 지금의 error, debug에 해당한다.
- File과 Console Handler를 지원.
- File은 직접 핸들링, Console은 System.err사용
FileHandler fileHandler = new FileHandler("status.log");
logger.addHandler(fileHandler);
1
2
2
- 일관성 문제, 느린 성능, 부족하지만 복잡한 설정, 구린 문서화로 불만 (opens new window)이 많았다.
# Log4j
- 오랜 시간 사랑받아온 기념비적인 로거
- 최초 만든 사람은 Ceki Gülcü (opens new window)
- 2001년부터 시작해서 2015년까지 아파치 재단 하에 유지 보수 되었다.
org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(MyClass.getClass().getName());
logger.info("This is an info message");
logger.error("This is an error message");
logger.debug("Here is a debug message");
1
2
3
4
2
3
4
- error, debug 레벨 정립
- 많은 appender 제공
- SMTPAppender: email 전송
- SyslogAppenders: 원격 데몬 전송
- JdbcAppenders: DB 저장
- 기타 (opens new window)
- PatternLayout (opens new window) 최초 도입. 로그 레이아웃 커스텀 가능
바로 이 분!
세키님
# Apache Commons Logging (JCL)
- 비슷한 시기 2002년 태어난 로거
- Jakarta Commons Logging(JCL)이라고도 불린다.
- 구현없는 오직 인터페이스 덩어리. 따라서 구현체 필요
org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(MyApp.class);
log.info("This is an info message");
log.error("This is an error message");
log.debug("Here is a debug message");
1
2
3
4
2
3
4
- 기냥 바로 log4j쓰면 안되나? 왜 필요할까?
- 다른 사용자를 위한 라이브러리를 작성한다고 가정해보자. 나는 log4j를 사용했는데, 다른 사용자는 다른 로거를 사용중에 있다면 충돌이 일어날 것이다. 인터페이스로만 참고하면 사용자마다 다른 구현체를 사용해도 문제없다.
- 레거시 코드를 유지보수할때 로거 변경이 힘들 경우, 인터페이스 로거로 브릿지해서 종속성을 끊는다.
- 문제점
- runtime에 로거 구현체가 로딩되는데, 구현체를 찾는 과정에서 classloader와 의존문제가 발생(자세한건 세키가 직접 작성한 여기 (opens new window)서 확인)
# Modern Logging Libraries
# SLF4J & Logback
log4j를 만든 세키가 뛰쳐나와 자체적으로 새로운 로깅 프로젝트를 착수한다. 대략 2005년쯤 인듯
이름하야 Logback
QOS.sh (opens new window)에서 유지 보수
더 강려크한 성능, 더 다양한 기능, test에 친화적, 문서 보강, 자동 설정, 우아한 오류처리등(자세한건 여기 (opens new window))
동시에 JCL 같은 Facade(혹은 Bridge) 인터페이스 덩어리 SLF4j 도 개발
- 따라서 구현체 필요
- logger.isDebugEnabled 사용할 필요가 없음
- 컴파일 시점에 구현체 로거 선택됨
한 프로젝트에 여러 모듈이 다른 로거 사용 혹은 3rd파티 라이브러리들이 각각 다른 로거를 사용해도, 하나의 추상 로거 레이어로 감쌀 수 있다. xxx-over-slf4j로 끝나는 라이브러리가 이 용도(기존 로거는 exclude 해야함)
따라서 실제 자주 보게 되는 로거 구조는
- SLF4J
- 구현체(Logback, Log4j등)
- 한 프로젝트에 여러 로거를 통일 한다면 xxx-over-slf4j(log4j-over-slf4j, jul-to-slf4j등)
# Log4j2
- Log4j의 공식 후속작. 2014년 릴리즈
- 완전 새로 쓰여짐
- 인터페이스 api와 실 구현체 core로 구성
// Bridge api
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.2</version>
</dependency>
// 구현체 core
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.2</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- core는 slf4j와도 같이 쓸 수 있다.
- slf4j보다 개선된 점
- 비동기 로깅
- 람다식 가능
- 향상된 가비지 컬렉션
- String외 타입 지원
- 자세한 사항은 여기 (opens new window)참조
- 사실 일반적인 어플리케이션에서는 성능 향상 체감이 어렵다. 아주 복잡하고 큰 어플리케이션에서는 약간의 성능향상이 있다고 함
# Jbos Logging
- RedHat에서 유지보수
- Bridge 로거. 실 구현체 필요
- 하이버네이트에서 사용(하이버네이트도 RedHat에서 관리)
# 성능 비교
환경에 따라 다르겠지만, Log4j2가 logback보다 수치로는 두배정도 빠르다. 비동기 시에는 압도적으로 빠르다.
# 그래서 무엇을 쓸까
slf4j와 logback 조합이 가장 무난. 로그를 많이 남긴다 생각되면 log4j2