[공부] 프로그래밍/Spring・Spring Boot (JAVA)
Logback 구현 - 2
woodisco
2024. 5. 23. 15:12
♧ 전체 코드 : https://github.com/woodisco/spring-logback
GitHub - woodisco/spring-logback: Spring Logback 공부
Spring Logback 공부. Contribute to woodisco/spring-logback development by creating an account on GitHub.
github.com
MDC 구현
멀티스레드 환경에서 로드를 남길 때 사용하는 개념
로그 관리 시스템에서 사용되는 개념으로, 각 스레드에 특정한 진단 정보를 저장하고 이를 로그 메시지에 자동으로 포함시키는 기능을 제공합니다. MDC는 주로 Java의 로깅 프레임워크인 Log4j, SLF4J, Logback 등에서 사용됩니다.
▷ MDC의 주요 개념
・ 스레드 별 진단 정보:
MDC는 각 스레드에 독립적인 진단 정보를 저장합니다. 예를 들어, 웹 애플리케이션에서 각 요청을 처리하는 스레드는 고유한 요청 ID를 가질 수 있으며, 이 요청 ID를 MDC에 저장할 수 있습니다.
・ 자동 로그 추가:
로그 메시지를 기록할 때, MDC에 저장된 진단 정보가 자동으로 로그 메시지에 추가됩니다. 이를 통해 로그를 분석할 때 어떤 요청이나 사용자와 관련된 로그인지 쉽게 식별할 수 있습니다.
① MdcController 작성
: put 이후에는 무조건 clear 해주기.
@Slf4j
@RestController
public class MdcController {
@GetMapping("/mdc")
public String mdc() {
MDC.put("job", "dev");
log.trace("log --> TRACE");
log.debug("log --> DEBUG");
log.info("log --> INFO");
log.warn("log --> WARN");
log.error("log --> ERROR");
MDC.clear();
return "mdc";
}
}
② logback-spring-prod.xml 수정
: %X 를 사용하면 mdc안에 있는 값을 key로 조회할 수 있다.
<appender name="MDC" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/mdc.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archive/mdc.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
<maxFileSize>1KB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>[MDC] %X{job}%n</pattern>
<outputPatternAsHeader>true</outputPatternAsHeader>
</encoder>
</appender>
// root 태그에 추가하기
<appender-ref ref="MDC" />
로그 필터링
: error로그만 필터링 해보기.
+ apprender 추가하기
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch> <!-- error만 받도록 설정 -->
<onMismatch>DENY</onMismatch> <!-- error이외에는 거절 -->
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archive/error.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<outputPatternAsHeader>true</outputPatternAsHeader>
</encoder>
</appender>
// root 태그에 추가하기
<appender-ref ref="ERROR" />
커스텀 로그
① QueryController1 작성
@Slf4j
@RestController
public class QueryController1 {
@GetMapping("/query1")
public String query() {
log.trace("log --> TRACE");
log.debug("log --> DEBUG");
log.info("log --> INFO");
log.warn("log --> WARN");
log.error("log --> ERROR");
return "Query";
}
}
② logback-spring-prod 수정
: logger 추가하기.
<logger name="SQL_LOG1" level="INFO" additivity="false">
<appender-ref ref="QUERY"/>
</logger>
<logger name="SQL_LOG2" level="INFO" additivity="false">
<appender-ref ref="QUERY"/>
</logger>
additivity는 상위 Logger 속성의 상속 여부를 정한다.
+ appender 추가하기
<appender name="QUERY" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/query.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archive/query.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
<maxFileSize>1KB</maxFileSize>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<outputPatternAsHeader>true</outputPatternAsHeader>
</encoder>
root 태그가 아닌 logger를 추가했기 때문에 해당 controller에 topic 설정하기
@Slf4j(topic = "SQL_LOG1")
③ QueryController2 작성
: 설정해 준 SQL_LOG2를 log로 컨트롤러에서 사용하기.
이 떼 @Slf4j 어노테이션은 지워야 한다. 하나의 컨트롤러에 log를 두 개 선언 할 필요가 없기 때문이다.
@RestController
public class QueryController2 {
public static final Logger log = LoggerFactory.getLogger("SQL_LOG2");
@GetMapping("/query2")
public String query() {
log.trace("log --> TRACE");
log.debug("log --> DEBUG");
log.info("log --> INFO");
log.warn("log --> WARN");
log.error("log --> ERROR");
if (true) {
throw new RuntimeException();
}
return "Query";
}
}
출처 : 패스트캠퍼스 10개 프로젝트로 완성하는 백엔드 웹개발(Java/Spring) 초격차 패키지 Online