SLF4J
Simple Logging Facade For Java
SLF4J는 다양한 Logging Framework(java.util.logging, logback, log4j)의 추상화를 제공합니다.
SLF4J는 Compile 시 하나의 logging framework와 binding 해줍니다.
SLF4J의 이점
- 가장 큰 것은 다양한 Logging Framework를 라이브러리만 추가해서 바인딩 할 수 있습니다.
- Deployment Time 에 Log Library 와 동적으로 연결합니다. 이 말은 Log Library만 변경하면 로그 엔진을 바꿀수 있습니다.
- 사용 시 약간의 이점도 있습니다.
아래의 코드는 string concat 연산을 하고나서, Logging Level 을 확인합니다.
만약 Level 이 Info 였다면 String 연산이 쓸데없는게 되겠죠.
logger.debug("Debug : " + msg);
그래서 아래와 같이 처리를 하곤했죠.
if(logger.isDebugEnabled()){
logger.debug("Debug : " + msg);
}
로그를 찍을 때마다??
이때 slf4j 를 이용하면,
logger.debug("Debug : {}", msg);
logging level을 먼저 확인하고, 로그를 출력 해야한다면 String 연산을 수행합니다.
Log Library 의 선택 - Logback
제가 예전 ( 한 7년전 ?? ㅋ )에 개발할 때 java 의 로깅 하면 log4j 였죠. 그밖에 다른 언어에서도 log4xx 시리즈가 많았습니다.
“Logback“은 새롭게 개발된게 아니라, 오랫동안 검증된 “LOG4J”의 아키텍쳐 기반으로 재작성 되었습니다.
특히 성능은 약 10배 정도 빠르게 개선을 했고, 또한 메모리 점유도 보다 적게 사용을 합니다.
Logback 을 더 선호하는 이유는
- 더 빠른 구현 : Log4j보다 최대 10배 빠르다.
- Extensive battery of tests : Log4j보다 테스트가 많이되었다.
- logback-classic speaks SLF4J natively : SLF4J API를 바로 구현하여 오버헤드가 없음.
- 광범위한 문서 : Logback은 상세하고 지속적으로 업데이트되는 문서와 함께 제공됩니다.
- Log4j의 문제 수정 - Multi-process가 1개의 File에 로그를 남길 수 있다. / Log archive의 Backup 개수를 지정할 수 있다.
- StackTrace에 그 Class가 속한 Library정보도 보여준다.
- Log4j보다 다양한 종류의 Appender 제공
- Dynamic Reloading 기능을 지원
logback 설정 파일 찾는 과정
- resources 디렉토리에서 logback.groovy
- resources 디렉토리에서 logback.xml
- 기본설정 적용
스프링에서는 logback-spring.xml로 작성할 것을 권장한다. (특히 커스텀 할 경우)
logback.xml 의 예제들
기본
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
환경별
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
<!-- dev env -->
<springProfile name="dev">
<logger name="org.springframework.boot" level="WARN" />
<logger name="org.springframework.web" level="DEBUG" />
</springProfile>
<!-- prod env -->
<springProfile name="prod">
<logger name="org.springframework.*" level="info" />
</springProfile>
</configuration>
- springProfile 은 application.properties 또는 yml 에 작성하면 됩니다.
spring.profiles.active = dev
- 위처럼 하나의 설정 파일안에 전부 작성할 수 도 있고, 아래처럼 각각 파일을 만들어서 관리할 수 있습니다.
spring.profiles.active=dev
logging.config=classpath:logback-${spring.profiles.active}.xml
- logback-dev.xml, logback-prod.xml 처럼 만들어 놔야겠죠.
기능별
<configuration debug="true">
<property name="FILE_LOG_ROOT" value="." />
<include resource="logback/logback-appender.xml"/>
<logger name="org.springframework" level="INFO"/>
<logger name="org.mybatis" level="INFO"/>
<logger name="org.apache.http" level="INFO"/>
<logger name="org.elasticsearch" level="INFO"/>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Rolling file
- 콘솔에는 모든 log 출력
- info 이상만 파일로 출력
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}[%-5level] : %msg%n</pattern>
</encoder>
</appender>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<file>log.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>log-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>[%-5level] %d{HH:mm:ss.SSS} %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLING"/>
</root>
</configuration>
console 과 file 의 또 다른 예제
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_DIR" value="/Users/user/logs"></property>
<property name="LOG_PREFIX" value="preword"></property>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${LOG_PREFIX}.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d{yyyy-MM-dd HH:mm:ss}- %-5level - %msg%n</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archived/${LOG_PREFIX}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="FILE"></appender-ref>
<appender-ref ref="STDOUT"></appender-ref>
</root>
</configuration>
그 외
<!-- logback 자체 로그를 출력하지 않음 -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
- 기본 Appendar
- ConsoleAppender : 로그를 콘솔에 출력
- FileAppender : 로그를 지정 파일에 기록
- RollingFileAppender : FileAppender을 상속. 날짜와 용량등을 설정해서 패턴에 따라 로그가 각기 다른파일에 기록되게 할 수 있음.
- 로그 레벨 : TRACE > DEBUG > INFO > WARN > ERROR
( Fatal 이 없음 )
글이 너무 길어졌네요.
여기까지 하고, 다음엔
시리즈 포스팅인 SpringBoot project 에 Logback 적용하는걸로 정리해보겠습니다.
Spring Boot Tutorial 시리즈
- 2021.07.03 - [Java] - [SpringBoot] RestApi 만들기 (1) 프로젝트 생성
- 2021.07.03 - [Java] - [SpringBoot] RestApi 만들기 (2) JSON 형식 리턴
- 2021.07.04 - [Java] - [SpringBoot] RestApi 만들기 (3) Log (slf4j+logback)
- 2021.07.04 - [Java] - [SpringBoot] RestApi 만들기 (4) Service 생성 (의존성 주입)
- 2021.07.04 - [Java] - [SpringBoot] RestApi 만들기 (5.1) MySQL + JDBC Template. 1
- 2021.07.05 - [Java] - [SpringBoot] RestApi 만들기 (5.2) DBCP - HikariCP
- 2021.07.08 - [Java] - [SpringBoot] RestApi 만들기 (5.3) jdbcTemplate - Select
- 2021.07.10 - [Java] - [SpringBoot] RestApi 만들기 (5.4) GetMapping, PostMapping
- 2021.07.10 - [Java] - [SpringBoot] RestApi 만들기 (5.5) jdbcTemplate - Insert, Update, Delete
Spring Boot Tutorial 부록
- 2021.07.02 - [Java] - [eclipse] 이클립스 설치, STS(Spring Tools 4) 설치
- 2021.07.04 - [Java] - [SpringBoot] MyBatis 보다 Spring JDBC 를 사용해야 하는 이유
- 2021.06.19 - [Java] - [Spring-boot] 시작하기 전 알아야 할 것들
- 2021.06.19 - [Java] - [Spring-boot] 수동으로 설정 초기화
- 2021.07.04 - [Java] - Eclipse 에 groovy 설치 하기
- 2021.07.02 - [Java] - [eclipse] 이클립스 설치, STS(Spring Tools 4) 설치
- 2021.07.07 - [Java] - [SpringBoot] Controller 에 Route 적용 (RequestMapping)
'Java' 카테고리의 다른 글
[SpringBoot] RestApi 만들기 (4) Service 생성 (의존성 주입) (4) | 2021.07.04 |
---|---|
[SpringBoot] RestApi 만들기 (3) Log (slf4j+logback) (2) | 2021.07.04 |
[SpringBoot] RestApi 만들기 (2) JSON 형식 리턴 (2) | 2021.07.03 |
[SpringBoot] RestApi 만들기 (1) 프로젝트 생성 (4) | 2021.07.03 |
[eclipse] 이클립스 설치, STS(Spring Tools 4) 설치 (10) | 2021.07.02 |
댓글