📝
땡칠로그/📝로그 분리 및 롤링 - Vingle

로그 분리 및 롤링 - Vingle

태그
로깅
slf4j
logback
개발
기술
완료 일시
Jun 11, 2024
notion image
현재 서버가 자주 터지는 원인 중 하나.
혹시 모를 오류에 대비하고자 모든 요청/쿼리를 로깅해왔다.
그러나 이제 더 이상 필요없는 상태. 인프라 보완하면서 한번에 하려고 미루다가 일단 이거먼저 하기로 했다.
 
이렇게 로깅하면 1차로 IO 처리량 자체가 많아 부담이 있다. (심지어 동기로 이뤄지고 있다)
2차로 파일로 저장되는 로그들이 점점 사이즈가 커지면서 서버의 디스크 사용량을 99.9%까지 올린다.
Disk Usage 99.9%는 브레이크가 고장난 8톤트럭이기 때문에 어떤 문제가 생길지 알 수 없다.
가장 자주 일어났던 일은 메인 서버의 크래시(비정상종료).
이걸로 지금까지 다운타임 총합 5시간은 잡아먹은듯 하여 팀에 미안했다 ㅠㅠ
 
운영 환경에서는 trace 및 debug 수준까지는 필요없고, 보수적으로 잡아서 INFO 이상만 기록되면 되겠다.
대신 개발 서버에서는 개발 편의성을 위해 쿼리도 별도로 로깅하고 싶다.
TRACE DEBUG INFO WARN ERROR FATAL <-- More verbose ... Less verbose -->
기본적으로 6단계정도이고, 당연히 커스텀 로깅 레벨을 추가할수도 있다.
INFO 레벨로 설정하면, 그 이상은 당연히 기록된다.
 
실제 설정에 들어가보자.
스프링 부트는 이미 로깅 프레임워크를 사용하고 있다.
Slf4j 추상화를 통해 Logback을 기본으로 사용한다.
(로깅 프레임워크 선택은 필요성을 느낄때 하고, 일단은 로그 레벨 조절 및 로깅 목적부터 달성하도록 하자)
Logback이 실행 시 기본으로 뒤지는 경로들이 있는데, src/main/resources/logback-spring.xml이 그 중 하나다. (‣ 참고)
 
우선 Appender, 즉 출력 관리 구현체를 생성해준다.
<included> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${LOG_PATTERN}</pattern> </encoder> </appender> </included>
Console appender. Nothing special.
<included> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <encoder> <pattern>${LOG_PATTERN}</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>./log/%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>1GB</totalSizeCap> </rollingPolicy> </appender> </included>
일반적인 로그를 모두 기록할 File appender이다
<included> <appender name="QUERY" class="ch.qos.logback.core.rolling.RollingFileAppender"> <encoder> <pattern>${LOG_PATTERN}</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>./log/query-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>2GB</totalSizeCap> </rollingPolicy> </appender> </included>
특히 개발서버에서 쿼리를 별도로 기록할 Query appender이다.
<?xml version="1.0" encoding="UTF-8"?> <configuration> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %clr(%5level) %cyan(%logger) - %msg%n"/> <springProfile name="local || test"> <include resource="log.appender/console-appender.xml"/> <include resource="log.appender/query-temporary-appender.xml"/> <root level="INFO"> <appender-ref ref="CONSOLE"/> </root> <logger level="DEBUG" name="org.hibernate.SQL" additivity="false"> <appender-ref ref="QUERY-TEMP"/> </logger> <logger level="TRACE" name="org.hibernate.type.descriptor.sql.BasicBinder" additivity="false"> <appender-ref ref="QUERY-TEMP"/> </logger> <logger level="TRACE" name="org.hibernate.orm.jdbc.bind" additivity="false"> <appender-ref ref="QUERY-TEMP"/> </logger> </springProfile> <springProfile name="dev"> <include resource="log.appender/file-appender.xml"/> <include resource="log.appender/query-file-appender.xml"/> <root level="INFO"> <appender-ref ref="FILE"/> </root> <logger level="DEBUG" name="org.hibernate.SQL" additivity="false"> <appender-ref ref="QUERY"/> </logger> <logger level="TRACE" name="org.hibernate.type.descriptor.sql.BasicBinder" additivity="false"> <appender-ref ref="QUERY"/> </logger> <logger level="TRACE" name="org.hibernate.orm.jdbc.bind" additivity="false"> <appender-ref ref="QUERY"/> </logger> </springProfile> <springProfile name="prod"> <include resource="log.appender/file-appender.xml"/> <root level="INFO"> <appender-ref ref="FILE"/> </root> </springProfile> </configuration>
그리고 마침내 앞서 언급한 세부사항을 모두 담은 로그백 설정. dev 프로파일에 query 어펜더가 있음을 확인할 수 있다. 또한 쿼리 관련 로깅은 별도의 파일에만 기록되고 root를 타지 않도록 additivity=false 로 설정했다

References