[Spring Boot] 로깅(Logging) 프레임워크 - Logback

조성우·2024년 1월 20일
0

Spring Boot

목록 보기
2/12
post-thumbnail

로깅(Logging)

  • 애플리케이션이 동작하는 동안 시스템의 상태나 동작 정보를 시간순으로 기록하는 것
  • 비기능 요구사항이나, 디버깅 및 문제 원인 분석을 위해 꼭 필요한 요소
  • log4j 이후 출시된 로깅 프레임워크로서 slf4j를 기반으로 구현됨 (월등한 성능)
  • 'spring-boot-starter-web' 라이브러리 내부에 내장되어 있음

Logback의 특징

  • 크게 5개의 로그 레벨을 설정할 수 있음
    • ERROR: 로직 수행 중에 시스템에 심각한 문제가 발생하여 애플리케이션 작동이 불가한 경우
    • WARN: 시스템 에러의 원인이 될 수 있는 경고 레벨
    • INFO: 애플리케이션의 상태 변경과 같은 정보 전달을 위해 사용
    • DEBUG: 애플리케이션의 디버깅을 위한 메시지를 표시하는 레벨
    • TRACE: DEBUG 레벨보다 더 상세한 메시지를 표현하기 위한 레벨
  • 실제 운영 환경과 개발 환경에서 각각 다른 출력 레벨을 설정해 로그 확인 가능
  • Logback의 설정 파일을 일정 시간마다 스캔해서 애플리케이션을 재가동하지 않아도 설정 변경 가능
  • 별도 프로그램 지원 없이 로그 파일 압축 가능
  • 저장된 로그 파일에 대한 보관 기간 등 설정 가능

Logback 설정

일반적으로 클래스패스(classpath)에 있는 설정 파일을 자동으로 참조하므로 Logback 설정 파일은 리소스 폴더 안에 생성함. 파일명의 경우 일반적인 자바 또는 스프링 프로젝트에서는 logback.xml 이름으로 참조하지만, 스프링 부트에서는 logback-spring.xml 파일을 참조함


resources/logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- Property 영역 -->
    <property name="LOG_PATH" value="./logs"/>  

    <!-- Appenders 영역 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
      	<!-- Encoder 영역 -->
        <encoder>
          	<!-- Pattern 영역 -->
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] %logger %msg%n</pattern>
        </encoder>
    </appender>

    <!-- Appenders 영역 -->
    <appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <file>${LOG_PATH}/info.log</file>
        <append>true</append>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/info_${type}.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
      	<!-- Encoder 영역 -->
        <encoder>
          	<!-- Pattern 영역 -->
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] %logger %msg%n</pattern>
        </encoder>
    </appender>

    <!-- TRACE > DEBUG > INFO > WARN > ERROR > OFF -->
    <!-- Root 영역 -->
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="INFO_LOG"/>
    </root>
</configuration>

Appender 영역

  • 로그의 형태를 설정하고 어떤 방법으로 출력할지를 설정하는 곳
  • Appender 자체는 하나의 인터페이스를 의미하며, 하위에 여러 구현체가 존재함
  • 아래 사진은 Appender의 상속 구조임
    • ConsoleAppender: 콘솔에 로그를 출력
    • FileAppender: 파일에 로그를 저장
    • RollingFileAppender: 여러 개의 파일을 순회하면서 로그를 저장
    • SMTPAppender: 메일로 로그를 전송
    • DBAppender: 데이터베이스에 로그를 저장
  • (코드 참고)
    • Appender 요소의 class 속성에 각 구현체를 정의
    • filter 요소를 통해 각 Appender가 어떤 레벨로 로그를 기록하는지 지정
    • encoder 요소를 통해 로그의 표현 형식을 패턴(pattern)으로 정의

      %logger: 패키지 포함 클래스 정보
      %logger{0}: 패키지를 제외한 클래스 이름만 출력
      %logger{length}: Logger name을 축약할 수 있음. {length}는 최대 자리 수, ex)logger{35}
      %-5level: 로그 레벨, -5는 출력의 고정폭 값(5글자), 로깅레벨이i nfo일 경우 빈칸 하나 추가
      ${PID:-}: 프로세스 아이디
      %d: 로그 기록시간 출력
      %p: 로깅 레벨 출력
      %F: 로깅이 발생한 프로그램 파일명 출력
      %M: 로깅일 발생한 메소드의 명 출력
      %line: 로깅이 발생한 호출지의 라인
      %L: 로깅이 발생한 호출지의 라인
      %thread: 현재 Thread 명
      %t: 로깅이 발생한 Thread 명
      %c: 로깅이 발생한 카테고리
      %C: 로깅이 발생한 클래스 명 (%C{2}는 somePackage.SomeClass 가 출력됨)
      %m: 로그 메시지
      %msg: - 로그 메시지 (=%message)
      %n: 줄바꿈(new line)
      %%: %를 출력
      %r : 애플리케이션 시작 이후부터 로깅이 발생한 시점까지의 시간(ms)
      %d{yyyy-MM-dd-HH:mm:ss:sss}: %d는 date를 의미하며 중괄호에 들어간 문자열은 dateformat을 의미. 따라서 [2021-07-12 12:42:78]과 같은 날짜가 로그에 출력됨.
      %-4relative: %relative는 초 아래 단위 시간(밀리초)을 나타냄. -4를하면 4칸의 출력폼을 고정으로 가지고 출력. 따라서 숫자에 따라 [2021-07-12 12:42:78:232] 혹은 [2021-07-12 12:42:78:2332]와 같이 표현됨


root 영역

  • 정의된 Appender를 활용하려면 Root 영역에서 Appender를 참조해 로깅 레벨을 설정함
  • 만약 특정 패키지에 대해 다른 로깅 레벨을 설정하고 싶다면 root 대신 logger 사용
    • logger 요소의 name 속성에는 패키지 단위로 로깅이 적용될 범위를 지정하고, lever 속성으로 로그 레벨을 지정

Logback 적용하기

  • Logback은 출력할 메시지를, Appender에게 전달할 Logger 객체를 각 클래스에 정의해서 사용
@RestController
@RequestMapping("/api/v1/get-api")
public class GetController {
  // LOGGER 전역 변수로 Logger 객체 정의. 클래스 정보를 Logger에서 가져가게 함
  private final Logger LOGGER = LoggerFactory.getLogger(GetController.class);
  ...
}

  • 로그를 출력하는 코드
@GetMapping(value = "/name")
public String getName() {
    LOGGER.info("getName 메소드가 호출되었습니다.");  // info 레벨에서 로그 출력
    return "Flature";
}
@GetMapping(value = "/variable1/{variable}")
public String getVariable1(@PathVariable String variable) {
    LOGGER.info("@PathVariable을 통해 들어온 값 : {}", variable);  // 포매팅을 통해 변수값 로깅 가능
    return variable;
}

0개의 댓글