티스토리 뷰
❓ 로깅, 왜 필요한데?
- 버그에 대한 유용한 정보 제공
- 프로그램 성능에 관한 통계와 정보 제공
💁🏻♀️ 그냥 println으로 로깅하면 안되나요?
- 상황별로 로그를 조정, 처리 ❌
- 로그를 별도로 저장 ❌
- 대량의 로그를 print하면 성능↓
🔎 로깅 프레임워크
java,util.logging- Apache Commons logging
- Log4J
- Logback
- SLF4J (Simple Logging Facade for Java)
✔️ SLF4J
: 로깅 라이브러리들을 추상화해 놓은 것 (퍼사드 패턴 사용)
: SLF4J의 구상체로 Logback, Log4J2 등을 사용할 수 있음
💡 Logback과 Log4J2와 같은 로깅 프레임워크를 번갈아 싶을 때, 코드를 바꾸지 않기 위해서 나온 것
🔎 로그 레벨
: 어떠한 환경에 로그를 어느정도까지 남길까?를 결정하는 것
trace > debug > info > warn > error
❕ 로그를 남기는 것도 프로그램 성능에 어느정도 영향을 끼침
📌 Logger를 만들어보자 (by 로그 팩토리)
import org.slf4j.*;
public class OrderTester {
private static final Logger logger = LoggerFactory.getLogger(OrderTester.class);
// private final Logger logger = LoggerFactory.getLogger(this.getClass());
// private static final Logger logger = LoggerFactory.getLogger("com.example.demo.OrderTester");
...
}
❕ 로거 구현체를 직접 import해서 쓰면 안됨
❕ OrderTester가 로거의 이름이 되고, 나중에 이 이름으로 로깅을 제어
📌 Logger를 써보자
logger.info("logger name ⇒ {}", logger.getName()); // logger name ⇒ com.example.demo.OrderTester
❕ 스프링 부트를 이용하면 SLF4J가 자동으로 설정됨
📌 로깅 설정을 해보자 (Logback 설정)
: 보통 기본설정을 복사한 뒤 프로젝트에 맞게 수정
<!-- main.resources.logback.xml -->
<configuration>
<!-- appender는 어디(지금은 Console)에 어떤 포맷으로 로그를 남길 수 있는지 설정 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
</encoder>
</appender>
<!-- logger는 기본적으로 root를 따름 -->
<logger name="com.example.demo.OrderTester" level="warn" additivity="false">
<!-- appender-ref를 추가하면 root와 중첩되어 로그가 2번 찍힘 (해결책: additivity를 false로 설정) -->
<appender-ref ref="STDOUT" />
</logger>
<!-- root는 application class path 상에 있는 모든 로그에 적용 -->
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
✔️ pattern 태그 더 알아보기
: 패턴을 작성할 때 공식 문서에서 Conversion Word(로깅 이벤트를 문자열로 변환) 참고
<configuration>
<!-- property를 설정 -->
<property name="CONSOLE_LOG_PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- property를 가져와서 사용 -->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
- %d : 로깅 이벤트의 날짜 출력 (ex. %date{ISO8601})
- %thread : 현재 Thread name
- %-5level : 로그 레벨을 왼쪽 정렬(-), 최대 글자는 5
- %logger{length} : 로그이름을 축약, length는 최대 자릿수
- %msg : 로그 메시지
- %n : 개행
📌 파일에 로그를 저장해보자 (feat. appender 태그 더 알아보기)
<configuration>
<property name="LOG_PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n"/>
<!-- 타임스템프 설정 -->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" />
<!-- FileAppender 사용 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- 로그 파일이 저장될 위치 + 재시작할때마다 파일을 새로 생성 -->
<file>logs/kdt_${bySecond}.log</file>
<!-- 프로그램을 재시작하면 다 지우고 다시 -->
<append>false</append>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
<configuration>
<property name="LOG_PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n"/>
<!-- RollingFileAppender 사용 -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 로그 파일이 저장될 위치 -->
<file>logs/access.log</file>
<!-- 무슨 로그 파일을 어떻게 만들 것이냐를 설정 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingFilePolicy">
<fileNamePattern>logs/access-d%{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<!-- 프로그램을 재시작하면 다 지우고 다시 -->
<append>false</append>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="ROLLING_FILE" />
</root>
</configuration>
❕ 원래 RollingFileAppender를 사용하면 RollingPolicy와 TriggeringPolicy를 설정 해야 되는데 TimeBasedRollingFilePolic에는 이 2가지가 모두 정의되어 있음
❕ <file>logs/access.log</file>을 넣어줌으로써 최신 파일은 access.log에서 접근 가능
✔️ logback 설정파일을 찾는 순서
logback-test.xml → logback.groovy → logback.xml → BasicConfiguration (기본 설정 전략)
- logback 설정은 보통 resources 폴더 아래에 넣어줌
- test폴더는 main폴더를 import할 수 있음으로 main > logback.xml과 test > logback-test.xml이 충돌날 수 있음, 이럴 때 logback-test.xml를 적용하기 위해서 logback-test.xml이 1순위로 찾아짐
📌 로그가 예쁘게 찍히게 해보자
<configuration>
<!-- clr을 사용할 수 있게 설정 -->
<conversionRule
conversionWord="clr"
converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<!-- clr 적용 -->
<property name="LOG_PATTERN" value="%clr(%d{HH:mm:ss.SSS}){red} [%thread] %-5level %logger{36} -%kvp- %msg%n">
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingFilePolicy">
<fileNamePattern>logs/access-d%{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<append>false</append>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="ROLLING_FILE" />
</root>
</configuration>
❕ 컬러 변경이 되지 않는다면 해당 로그를 쓰는 클래스로 가서 AnsiOutput을 true로 변경
AnsiOutput.setEnabled(AnsiOutput.Enable.ALWAYS);
'백엔드 > Spring' 카테고리의 다른 글
Spring REST Docs를 적용해보자! (1) | 2023.11.21 |
---|---|
테스트 코드에 parameterized tests를 적용해보자! (1) | 2023.11.20 |
스프링 프레임워크의 핵심 개념들 (2) | 2023.10.10 |
[오류] JPAQueryFactory could not be found (0) | 2023.07.25 |
[스프링] 단축키 모음 (0) | 2023.07.07 |