💡 로깅 [logging]
시스템을 작동할 때 시스템의 작동 상태의 기록과 보존, 이용자의 습성 조사 및 시스
템 동작의 분석 등을 하기 위해 작동중의 각종 정보를 기록해둘 필요가 있다. 이 기록
을 만드는 것을 로깅이라 한다. 즉 로그 시스템의 사용에 관계된 일련의 「사건」을
시간의 경과에 따라 기록하는 것이다.
@Slf4j 어노테이션 사용법 편리 : https://programmer93.tistory.com/64
SLF4J(Simple Logging Façade For Java)란 Logging Framework들을 추상화해 놓은 것입니다. Facade Pattern을 이용한 Logging Framework입니다.
주의! Logger 설정은 이렇게 메인 메서드 위에서 설정한다.
public class OrderTester {
private static final Logger log = LoggerFactory.getLogger(OrderTester.class);
public static void main(String[] args) throws IOException {
var customerId = UUID.randomUUID();
var applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);
var environment = applicationContext.getEnvironment();
var version = environment.getProperty("kdt.version");
var minimumOrderAmount = environment.getProperty("kdt.minimum-order-amount", Integer.class);
log.info("version -> {}", version);
log.info("minimumOrderAmount -> {}", minimumOrderAmount);
var resource = applicationContext.getResource("application.yaml");
var resource2 = applicationContext.getResource("file:sample.txt");
log.info(resource2.getClass().getCanonicalName());
}
}
logback 설정파일 찾는 순서
1. logback-test.xml 파일을 먼저 찾습니다.
2. 없다면 logback.groovy 을 찾습니다.
3. 그래도 없다면 logback.xml을 찾습니다.
4. 모두 없다면 기본 설정 전략을 따릅니다. BasicConfiguration
logback configuration
http://logback.qos.ch/manual/configuration.html
Basic configuration file (main > java > org.prgms > resources > logback.xml)
<configuration>
<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="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
debug로 설정을 해서 로그가 다 찍히는 것을 볼 수 있다.
<configuration>
<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>
<logger name = "org.prgms" level="info"/>
<root level="warn"> <!-- debug 보다 높은 레벨 출력 -->
<appender-ref ref="STDOUT" />
</root>
</configuration>
이렇게 org.prmgs는 info level이다, 라고 따로 설정도 가능하다.
orderProperties 안에 log는 debug 라고 함
package org.prgms.order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.text.MessageFormat;
@Component
public class OrderProperties implements InitializingBean {
private final static Logger logger = LoggerFactory.getLogger(OrderProperties.class);
@Value("${kdt.version:v0.0.0}") // kdt.version 값을 못읽으면 v0.0.0 default 값
private String version;
@Value("3")
private Integer minimumOrderAmount;
@Override
public void afterPropertiesSet() throws Exception {
logger.debug(MessageFormat.format("version -> {0}", version));
logger.debug(MessageFormat.format("minimumOrderAmount -> {0}", minimumOrderAmount));
}
}
log가 어떻게 나올까?
debug는 info보다 낮은 레벨이기 때문에 찍히지 않는 것을 볼 수 있다!
orderProperties 안에 log를 info로 설정한다면?
package org.prgms.order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.text.MessageFormat;
@Component
public class OrderProperties implements InitializingBean {
private final static Logger logger = LoggerFactory.getLogger(OrderProperties.class);
@Value("${kdt.version:v0.0.0}") // kdt.version 값을 못읽으면 v0.0.0 default 값
private String version;
@Value("3")
private Integer minimumOrderAmount;
@Override
public void afterPropertiesSet() throws Exception {
logger.info(MessageFormat.format("version -> {0}", version));
logger.info(MessageFormat.format("minimumOrderAmount -> {0}", minimumOrderAmount));
}
}
이렇게 부분별로 나눌 수 있다!
PatternLayout
Logback이 기본적으로 제공한는 패턴레이아웃을 이용하면 우리가 로거에서 만든 로깅 이벤트를 가지고 문자열을 변환할 수 있습니다. 이때 문자열로 변환될때 conversion specifiers 라는걸 이용한다.
http://logback.qos.ch/manual/layouts.html
<configuration>
<property name="LOG_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<timestamp key = "bySecond" datePattern = "yyyyMMdd'T'HHmmss"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<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>
<logger name = "org.prgms" level="debug">
<appender-ref ref = "FILE"/>
</logger>
<root level="warn"> <!-- debug 보다 높은 레벨 출력 -->
<appender-ref ref="STDOUT" />
</root>
</configuration>
FILE appender를 추가하면 kdt_20210822T003648.log가 생성된다(오늘 기준 8/22)
<configuration>
<property name="LOG_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/access.log</file>
<rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/access-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<logger name = "org.prgms" level="debug">
<appender-ref ref = "ROLLING_FILE"/>
</logger>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
롤링파일을 이용하면 현재 날짜 기준으로 파일은 access.log가 생성되며, 만약 하루가 지나면 이 access.log 파일이 access-2021-8-22.log파일로 바뀌게 된다.
장점은 현재 날짜 폴더는 access이기 때문에 날짜를 몰라도 된다는 장점을 가지고 있다!
https://docs.spring.io/spring-boot/docs/2.5.1/reference/htmlsingle/#howto.logging.logback
10.7.1 base.xml 참고
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/bokzip.log</file>
<rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/bokzip-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="CONSOLE" />
</root>
<logger name="org.springframework" level="warn">
<appender-ref ref = "ROLLING_FILE"/>
</logger>
</configuration>
SpringBoot Banner 제너레이터
https://patorjk.com/software/taag/#p=testall&f=Graffiti&t=bokzip