Spring Boot 로그 설정 - Logback 활용 가이드

Spring Boot 로그 설정 - Logback 활용 가이드

  1. Logback 사용의 이점
  • Logback은 Spring Boot의 기본 통합 로깅 프레임워크로, SLF4J를 기반으로 합니다.
  • Logback의 커널은 재설계되어 주요 경로에서 약 10배의 성능 향상과 메모리 사용량 감소를 달성했습니다.
  • Logback은 상세하고 지속적으로 업데이트되는 문서를 제공합니다.
  • Logback은 I/O 오류에서 자동으로 복구할 수 있습니다. 파일 서버가 일시적으로 실패해도 애플리케이션 재시작 없이 로그 기록을 다시 시작할 수 있으며, 파일 서버가 복구되면 관련 logback appender가 이전 오류 상태에서 자동으로 빠르게 복구됩니다.
  1. Spring Boot 프로젝트에서 Logback 기본 사용법

Logback은 Spring Boot 프로젝트의 기본 통합 로깅 프레임워크입니다. 기본 설정 환경에서는 INFO 수준 이상의 로그 정보만 콘솔에 출력됩니다. 로그 파일을 특정 파일로 출력하려면 application.properties 또는 application.yml 파일에 로그 파일 출력 경로와 이름을 추가할 수 있습니다.

// 로그 파일 설정 (절대 경로 또는 상대 경로 가능)
logging.file=xxx.log
// 로그 파일 저장 디렉토리 설정, 해당 디렉토리에 spring.log 파일 생성
logging.path=/logs
// 주의: 두 설정은 동시에 사용할 수 없음, 동시 사용 시 logging.file만 적용됨
  1. 프로젝트 요구사항에 맞는 Logback 사용자 정의 설정 파일

Spring Boot 프로젝트는 클래스 경로(classpath:)에서 logback.xml과 logback-spring.xml(spring 공식 권장 설정 파일 이름) 파일을 자동으로 스캔합니다. 찾지 못하면 Spring의 기본 logback 설정 파일을 사용합니다. 따라서 사용자 정의 logback 설정 시 logback.xml과 logback-spring.xml 파일에서 우선적으로 작성하는 것이 좋습니다. 다른 형식의 경우에도 logback-으로 파일 접두사를 사용해야 하며, application.properties에서 logging.config=을 사용하여 로그 설정 파일 위치를 지정해야 합니다.

logging.config=classpath:logging-xxx.xml
  1. 설정 파일 작성 전 숙지해야 할 핵심 개념
  • 루트 노드 : 파일의 모든 내용이 이 루트 노드에 포함되며, 다음 세 가지 속성을 포함합니다
  • scan: 기본값은 true이며, 이 속성값이 true로 설정되면 설정 파일이 변경되면 다시 로드됩니다
  • scanPeriod: 설정 파일 변경을 감지할 시간 간격을 설정하며, 시간 단위가 지정되지 않으면 기본 단위는 밀리초입니다. scan이 true일 때 이 속성이 유효합니다. 기본 간격은 1분입니다.
  • debug: 기본값은 false이며, 이 속성이 true로 설정되면 logback의 내부 로그가 출력되어 logback의 실행 상태를 실시간으로 확인할 수 있습니다.
<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
    ...... 
</configuration>
  • 자식 노드 : 컨텍스트의 이름을 설정하며, 기본 컨텍스트 이름은 default이지만 을 사용하여 다른 이름으로 설정할 수 있습니다. 서로 다른 애플리케이션의 기록을 구분하는 데 사용됩니다.
<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
    <contextName>dimples-logback</contextName> 
    ......
</configuration>
  • 자식 노드 : 변수를 정의하며, name과 value 두 가지 속성이 있습니다. logger 파일에서 ${}를 사용하여 name에 해당하는 property의 value 값을 가져올 수 있습니다.
  • 자식 노드 : 로그의 특정 기능과 내용을 구성하는 노드로, name과 class 속성이 있으며, class를 통해 로그 처리 유형을 지정합니다. 다음 두 가지가 일반적으로 사용됩니다.
ch.qos.logback.core.ConsoleAppender: 로그를 콘솔에 출력

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <!-- 로그 출력 형식 설정 -->
        <Pattern>${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</Pattern>
        <!-- 콘솔도 UTF-8을 사용해야 하며, GBK를 사용하면 중국어가 깨짐 -->
        <charset>UTF-8</charset>
    </encoder>
</appender>
ch.qos.logback.core.rolling.RollingFileAppender: 롤링 파일 기록

<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
   <!-- 현재 기록 중인 로그 파일의 경로 및 파일 이름 -->
   <file>C:/springboot-log/logs/info/log_info.log</file>
   <!--로그 정보 출력 형식-->
   <encoder>
       <!-- 로그 출력 형식 설정 -->
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
      <!-- 로그 출력 인코딩 -->
      <charset>UTF-8</charset>
   </encoder>
   <!-- 로그 레코더의 롤링 정책, 날짜 및 크기 기준으로 기록 -->
   <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- 매일 로그 아카이브 경로 및 형식 -->
      <fileNamePattern>C:/springboot-log/logs/info/log-info-%d{yyyy-MM-dd-HH}.%i.log</fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy
         class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
         <!-- 개별 로그 파일의 최대 크기 -->
         <maxFileSize>100MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
      <!-- 로그 파일 보존 일수 -->
      <maxHistory>15</maxHistory>
   </rollingPolicy>
   <!-- 로그 파일 기록 수준 설정, 예: info 수준만 기록 -->
   <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>info</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
   </filter>
</appender>
  • 위 두 가지 로그 처리 유형 외에도 다음과 같은 다른 유형이 있습니다:
  1. FileAppender: 로그를 파일에 추가하는 일반적인 방법
  2. SocketAppender
  3. SMTPAppender
  4. DBAppender
  5. SyslogAppender
  6. SiftingAppender 등

마지막으로, 일반 프로젝트에서 요약한 logback 설정 파일을 공유합니다. debug, info, warn, error 네 가지 유형의 로그 정보를 각각 네 개의 폴더에 저장하고, 크기와 날짜에 따라 아카이브합니다. 대부분의 비즈니스 시나리오를 충족합니다.

<?xml version="1.0" encoding="UTF-8"?>
<!-- 로그 수준은 TRACE < DEBUG < INFO < WARN < ERROR < FATAL 순으로 낮음, WARN으로 설정하면 WARN보다 낮은 정보는 출력되지 않음 -->

<!-- 루트 노드<configuration>, 다음 세 가지 속성 포함:-->
<!-- scan: 이 속성이 true로 설정되면, 설정 파일이 변경되면 다시 로드됨, 기본값은 true.-->
<!-- scanPeriod: 설정 파일 변경을 감지할 시간 간격 설정, 시간 단위가 지정되지 않으면 기본 단위는 밀리초. scan이 true일 때 이 속성이 유효. 기본 시간 간격은 1분.-->
<!-- debug: 이 속성이 true로 설정되면 logback 내부 로그 정보가 출력되어 logback 실행 상태를 실시간으로 확인 가능. 기본값은 false.-->
<configuration>
   <contextName>dimples-logback</contextName>
   <!-- name은 변수 이름, value는 변수 정의 값. 정의된 값은 logger 컨텍스트에 삽입됨. 변수 정의 후 "${}"를 사용하여 변수를 사용할 수 있음. -->
   <property name="log.path" value="C:/springboot-log/logs" />

   <!-- 컬러 로그 -->
   <!-- 컬러 로그 종속 렌더링 클래스 -->
   <conversionRule conversionWord="clr"
      converterClass="org.springframework.boot.logging.logback.ColorConverter" />
   <conversionRule conversionWord="wex"
      converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
   <conversionRule conversionWord="wEx"
      converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
   <!-- 컬러 로그 형식 -->
   <property name="CONSOLE_LOG_PATTERN"
      value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
   <property name="log.colorPattern" value="%magenta(%d{yyyy-MM-dd HH:mm:ss}) %highlight(%-5level) %boldCyan([${springAppName:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]) %yellow(%thread) %green(%logger) %msg%n"/>
   <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level [${springAppName:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}] %thread %logger %msg%n"/>
   <!-- %m 출력 정보, %p 로그 수준, %t 스레드 이름, %d 날짜, %c 클래스 전체 이름, %i 인덱스[숫자 0부터 증가] -->
   <!-- appender는 configuration의 자식 노드로, 로그를 기록하는 구성 요소. -->
   <!-- ConsoleAppender: 로그를 콘솔에 출력 -->
   <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
         <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
         <!-- 콘솔도 UTF-8을 사용해야 하며, GBK를 사용하면 중국어가 깨짐 -->
         <charset>UTF-8</charset>
      </encoder>
   </appender>

   <!-- 시간 롤링 출력, DEBUG 수준 로그 -->
   <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <!-- 현재 기록 중인 로그 파일의 경로 및 파일 이름 -->
      <file>${log.path}\debug/log_debug.log</file>
      <!--로그 정보 출력 형식-->
      <encoder>
         <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
         <charset>UTF-8</charset> <!-- 문자셋 설정 -->
      </encoder>
      <!-- 로그 레코더의 롤링 정책, 날짜 및 크기 기준으로 기록 -->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <!-- 로그 아카이브 -->
         <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd-HH}.%i.log</fileNamePattern>
         <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>100MB</maxFileSize>
         </timeBasedFileNamingAndTriggeringPolicy>
         <!--로그 파일 보존 일수-->
         <maxHistory>15</maxHistory>
      </rollingPolicy>
      <!-- 이 로그 파일은 debug 수준만 기록 -->
      <filter class="ch.qos.logback.classic.filter.LevelFilter">
         <level>debug</level>
         <onMatch>ACCEPT</onMatch>
         <onMismatch>DENY</onMismatch>
      </filter>
   </appender>

   <!-- 시간 롤링 출력, INFO 수준 로그 -->
   <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <!-- 현재 기록 중인 로그 파일의 경로 및 파일 이름 -->
      <file>${log.path}\info/log_info.log</file>
      <!--로그 정보 출력 형식-->
      <encoder>
         <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
         <charset>UTF-8</charset>
      </encoder>
      <!-- 로그 레코더의 롤링 정책, 날짜 및 크기 기준으로 기록 -->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <!-- 매일 로그 아카이브 경로 및 형식 -->
         <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd-HH}.%i.log</fileNamePattern>
         <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>100MB</maxFileSize>
         </timeBasedFileNamingAndTriggeringPolicy>
         <!--로그 파일 보존 일수-->
         <maxHistory>15</maxHistory>
      </rollingPolicy>
      <!-- 이 로그 파일은 info 수준만 기록 -->
      <filter class="ch.qos.logback.classic.filter.LevelFilter">
         <level>info</level>
         <onMatch>ACCEPT</onMatch>
         <onMismatch>DENY</onMismatch>
      </filter>
   </appender>

   <!-- 시간 롤링 출력, WARN 수준 로그 -->
   <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <!-- 현재 기록 중인 로그 파일의 경로 및 파일 이름 -->
      <file>${log.path}\warn/log_warn.log</file>
      <!--로그 정보 출력 형식-->
      <encoder>
         <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
         <charset>UTF-8</charset> <!-- 문자셋 설정 -->
      </encoder>
      <!-- 로그 레코더의 롤링 정책, 날짜 및 크기 기준으로 기록 -->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd-HH}.%i.log</fileNamePattern>
         <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>100MB</maxFileSize>
         </timeBasedFileNamingAndTriggeringPolicy>
         <!--로그 파일 보존 일수-->
         <maxHistory>30</maxHistory>
      </rollingPolicy>
      <!-- 이 로그 파일은 warn 수준만 기록 -->
      <filter class="ch.qos.logback.classic.filter.LevelFilter">
         <level>warn</level>
         <onMatch>ACCEPT</onMatch>
         <onMismatch>DENY</onMismatch>
      </filter>
   </appender>
   <!-- RollingFileAppender: 파일 롤링 기록, 먼저 로그를 지정된 파일에 기록한 후 특정 조건이 충족되면 로그를 다른 파일에 기록 -->
   <!--             2. 날짜가 변경되지 않았지만 현재 로그 파일 크기가 1KB를 초과하면 현재 로그를 분할하고 이름 변경 -->
   <!-- 시간 롤링 출력, ERROR 수준 로그 -->
   <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <!-- 현재 기록 중인 로그 파일의 경로 및 파일 이름 -->
      <file>${log.path}\error/log_error.log</file>
      <!--로그 정보 출력 형식-->
      <encoder>
         <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
         <charset>UTF-8</charset> <!-- 문자셋 설정 -->
      </encoder>
      <!-- 로그 레코더의 롤링 정책, 날짜 및 크기 기준으로 기록 -->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd-HH}.%i.log</fileNamePattern>
         <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>100MB</maxFileSize>
         </timeBasedFileNamingAndTriggeringPolicy>
         <!--로그 파일 보존 일수-->
         <maxHistory>30</maxHistory>
      </rollingPolicy>
      <!-- 이 로그 파일은 ERROR 수준만 기록 -->
      <filter class="ch.qos.logback.classic.filter.LevelFilter">
         <level>ERROR</level>
         <onMatch>ACCEPT</onMatch>
         <onMismatch>DENY</onMismatch>
      </filter>
   </appender>
   <!--개발 환경: 콘솔에 출력-->
   <!-- 프로젝트에서 특정 패키지를 지정하여 로그 작업 동작 시 로그 기록 수준 -->
   <!-- com.dimples.springboot.biz는 비즈니스 로직 루트 패키지, 이 루트 패키지 아래에서 발생하는 모든 로그 작업 동작의 권한은 DEBUG -->
   <!-- 수준 순서는【높음에서 낮음】: FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
   <springProfile name="dev">
      <logger name="com.dimples.springboot.biz" level="debug" />
   </springProfile>
   <!-- 콘솔 출력 로그 수준 -->
   <root level="info">
      <appender-ref ref="CONSOLE" />
      <appender-ref ref="DEBUG_FILE" />
      <appender-ref ref="INFO_FILE" />
      <appender-ref ref="WARN_FILE" />
      <appender-ref ref="ERROR_FILE" />
   </root>

   <!--생산 환경: 파일에 출력-->
   <!--<springProfile name="pro">-->
   <!--<root level="info">-->
   <!--<appender-ref ref="CONSOLE" />-->
   <!--<appender-ref ref="DEBUG_FILE" />-->
   <!--<appender-ref ref="INFO_FILE" />-->
   <!--<appender-ref ref="ERROR_FILE" />-->
   <!--<appender-ref ref="WARN_FILE" />-->
   <!--</root>-->
   <!--</springProfile>-->
</configuration>

태그: Spring Boot Logback 로깅 로그 설정 SLF4J

7월 3일 18:42에 게시됨