프로그램 개발 중이나 완료 후 발생할 수 있는 오류에 대해 디버깅하거나 운영 중인 프로그램 상태를 모니터링 하기 위해 필요한 정보(로그)를 기록합니다.
다시말해 애플리케이션 실행에 대한 추적을 기록하기 위해 어딘가에 메시지 (콘솔, 파일, 데이터베이스 등)를 작성하는 것입니다.
주로 디버깅이나 사용자 상호 작용 기록(발생하는 이벤트 기록)에 사용됩니다.
native java.util.logging: 별로 사용하지 않는다.
Log4j : 콘솔로 출력하는 stdout 외에도 파일 출력도 제공, 2015년 개발 중단으로 레거시 시스템에서 사용
Logback : Log4J 개발자가 만든 Log4J의 후속 버전, Log4j보다 향상된 성능과 필터링 옵션 제공하며 slf4j 지원, 자동 리로드 가능
- SLF4J(Simple Logging Facade for Java): Log4J 또는 Logback과 같은 백엔드 Logger Framework의 facade pattern
Log4j2 : Logback과 동일하며 멀티 쓰레드 환경에서 비동기로거의 경우 Log4j 1.x 및 Logback
보다 처리량이 18배 더 높고 대기 시간이 짧은 장점이 있음.
tinylog : 사용하기 쉽게 최적화된 Java용 최소형(75KB Jar) 프레임워크
오류를 확인하기 위한 디버거와의 비교했을 때 장점은 무엇인가?
Logging은 응용 프로그램 실행에 대한 정확한 컨텍스트(이벤트 순서)를 제공한다.
A. 전체적인 app의 흐름이나 타이밍 error도 확인할 수 있다.
B. error 종류: 논리적 에러, 타이밍 에러(multi-thread) 등
일단 코드에 삽입되면 logging output이 만들어질 때 사용자 개입이 필요 없다.
로그 출력은 나중에 살펴볼 수 있도록 영구 매체에 저장할 수 있다.
A. disk에 기록을 남겨 유용한 로깅 정보를 추적할 수 있다.
Logging Framework는 Debuggger보다 간단하고 배우기 쉽고 사용하기 쉽다.
그렇다면 단점은 무엇인가?
출력문이 들어가기 때문에 응용 프로그램 속도를 늦출 수 있다.
메시지 Level 설정에 유의하여 로그 관리가 필요가 하다.
System.out.println()과의 차이점은 무엇인가?
우선순위를 선택할 수 있다.
모든 모듈 또는 특정 모듈 또는 클래스에 대해 로깅할 수 있다.
매개변수화된 로그 메시지 지원으로 로그 메시지 형식을 제어할 수 있다.
즉 Log4j는 출력 위치를 지정하는 등의 높은 유연성을 갖는다.
Log4j : Log for Java
로그문의 출력을 다양한 대상으로 할 수 있도록 도와주는 도구(오픈소스)
오픈소스 링크 : https://logging.apache.org/log4j/1.2/
log4j 는 속도에 최적화
log4j 는 이름있는 로그 계층에 기반
log4j 는 fail-stop 이지만 신뢰성은 없음
log4j 는 thread-safe(멀티스레드 환경에서 사용해도 안전하다:역주).
log4j 는 융통성이 풍부
설정 파일은 property 파일과 XML 형식으로 실행 중 수정 적용 가능
log4j 는 처음부터 자바의 예외를 처리하기 위해 디자인
log4j 는 출력을 파일, 콘솔, java.io.OutputStream, java.io.Writer, TCP 를 사용하는 원격서버, 원격 Unix Syslog 데몬, - 원격 JMS 구독자, 윈도우 NT EventLog 로 보낼 수 있고, 심지어는 e-mail 로 보낼 수도 있음
log4j 는 다음 6 단계의 장애레벨을 사용. < TRACE(추가), DEBUG, INFO, WARN, ERROR, FATAL >
로그 출력의 형식은 Layout 클래스를 확장함으로써 쉽게 바꿀 수 있음
로그가 출력될 대상과 출력 방법은 Appender 인터페이스로 할 수 있음
log4j 는 로거 하나에 다수의, 출력을 담당하는 appender 를 할당할 수 있음
log4j 는 국제화를 지원
구조 | 역할 |
---|---|
Logger(Category) | 로깅 메세지를 Apeender에 전달 log4J의 심장부에 위치 개발자가 직접 로그 출력 여부를 런타임에 조정 logger는 로그레벨을 가지고 있으며, 로그의 출력 여부는 로그문의 레벨과 로거의 레벨을 가지고 결정 |
Appender | 로그의 출력위치를 결정(파일, 콜솔, DB 등) log4J API 문서의 XXXAppender로 끝나는 클래스들의 이름을 보면, 출력위치를 어느정도 짐작 가능 |
Layout | Appender가 어디에 출력할 것인지 결정했다면 어떤 형식으로 출력할 것인지 출력 layout을 결정 |
레벨 | 설명 |
---|---|
FATAL | 아주 심각한 에러가 발생한 상태. 시스템적으로 심각한 문제가 발생해서 어플리케이션 작동이 불가능할 경우가 해당하는데, 일반적으로는 어플리케이션에서는 사용할 일이 없음 |
ERROR | 요청을 처리하는 중 문제가 발생한 상태를 나타냄 |
WARN | 처리 가능한 문제이지만, 향후 시스템 에러의 원인이 될 수 있는 경고성 메세지를 나타냄 |
INFO | 로그인, 상태변경과 같은 정보성 메세지를 나타냄 |
DEBUG | 개발시 디버그 용도롤 사용한 메세지를 나타냄 |
TRACE | log4j1.1.12에서 신규 추가된 레벨로서, DEBUG 레벨이 너무 광범위한 것을 해결하기 위해서 좀 더 상세한 상태를 나타냄 |
FATAL > ERROR > WARN > INFO > DEBUF > TRACE DEBUG 레벨로 했다면 INFO ~ FATAL까지 모두 logging 됨 |
일반적으로 PatternLayout 을 사용하는 것이 디버깅에 가장 적합함
옵션 | 설명 |
---|---|
%p | debug, info, warn, error, fatal 등의 priority 출력 |
%m | 로그내용 출력 |
%d | 로깅 이벤트가 발생한 시간을 출력 ex. 포멧은 %d{HH:mm:ss} 같은 형태의 SimpleDataFormat |
%t | 로그이벤트가 발생된 쓰레드의 이름 출력 |
%F | 로깅이 발생한 프로그램 파일명 출력 |
%I | 로깅이 발생한 caller의 정보 출력 |
%L | 로깅이 발생한 caller의 라인수 출력 |
%M | 로깅이 발생한 method 이름 출력 |
% | % 표시 출력 |
%n | 플랫폼 종속적인 개행문자 출력 |
%c | 카테고리 출력 ex. 카테고리가 a.b.c 처럼 되어있다면 %c{2}는 b.c 출력 |
%C | 클래스명 출력 ex. 클래스구조가 org.apache.xyz.SomeClass 처럼 되어있다면 %C{2}는 xyz.SomeClass 출력 |
%r | 어플리케이션 시작 이후 부터 로깅이 발생한 시점의 시간(milliseconds) 출력 |
%x | 로깅이 발생한 thead와 관련된 NDC(nested diagnostic context) 출력 |
%X | 로깅이 발생한 threan와 관련된 MDC(mapped diagnostic context) 출력 |
클래스 | 설명 |
---|---|
ConsoleAppender | org.apache.log4j.ConsoleAppender 콘솔에 로그 메시지 출력 |
FileAppender | org.apache.log4j.FileAppender 파일에 로그 메시지 기록 |
RollingFileAppender | org.apache.log4j.rolling.RollingFileAppender 파일 크기가 일정 수준 이상이 되면 기존 파일을 백업파일로 바꾸고 처음부터 |
기록 | |
DailyRollingFileAppender | org.apache.log4j.DailyRollingFileAppender 일정 기간 단위로 로그 파일을 생성하고 기록 |
JDBCAppender | org.apache.log4j.jdbc.JDBCAppender DB 에 로그를 출력. 하위에 Driver, URL, User, Password, Sql 과 같은 parameter 를 정의할 수 있음 |
SMTPAppender | 로그 메시지를 이메일로 전송 |
NTEventAppender | 윈도우 시스템 이벤트 로그로 메시지 전송 |
출처: https://cofs.tistory.com/354
MVN Repository 에서 log4jdbc 검색 → Log4Jdbc Log4j2 JDBC 선택→ 버전 맞게 복사해서 pom.xml 파일에 붙여넣기
<!-- Logging -->
<!-- Log4JDBC -> MVN REPOSITORY에서 가져옴! -->
<!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4.1 -->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
<!-- 로깅 레벨 정리 -->
<!-- (ALL), DEBUG, INFO, WARN, ERROR, FATAL, (OFF) -->
<!--
1. jdbc.connection : 열려있는 연결 수립 및 해제 이벤트를 기록, 연결문제를 찾아내느데 유용함.
2. jdbc.sqltiming : SQL문과 해당 SQL을 실행시키는데(수행하는데) 걸린 시간 정보를 포함.
3. jdbc.sqlonly : SQL문만 로그를 남김, PreparedStatement일 경우 ?(위치홀더)값이 완전히 보임.
4. jdbc.audit : ResultSet을 제외한 모든 JDBC호출 정보를 로그로 남김. 로그양이 많고
필요하지 않으면 사용하지 않음.
5. jdbc.resultset : ResultSet을 포함한 모든 JDBC호출 정보를 로그로 남김, 로그양이 많음.
6. jdbc.resultsettable : SQL결과 조회된 데이터의 table을 그려줌.
-->
<logger name="jdbc.connection" additivity="false">
<level value="WARN" />
<appender-ref ref="console" />
</logger>
<logger name="jdbc.sqltiming" additivity="false">
<level value="WARN" />
<appender-ref ref="console" />
</logger>
<logger name="jdbc.sqlonly" additivity="false">
<level value="INFO" />
<appender-ref ref="console" />
</logger>
<logger name="jdbc.audit" additivity="false">
<level value="WARN" />
<appender-ref ref="console" />
</logger>
<logger name="jdbc.resultset" additivity="false">
<level value="WARN" />
<appender-ref ref="console" />
</logger>
<logger name="jdbc.resultsettable" additivity="false">
<level value="WARN" />
<appender-ref ref="console" />
</logger>
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"></property>
<property name="url" value="jdbc:log4jdbc:oracle:thin:@127.0.0.1:1521:XE"></property>
<property name="username" value="SPRING"></property>
<property name="password" value="SPRING"></property>
</bean>
</beans>