[Spring] 로깅 라이브러리(Logback)

WOOK JONG KIM·2022년 10월 26일
0
post-thumbnail

Logging : 애플리케이션이 동작하는 동안 시스템의 상태나 동작 정보를 시간숙으로 기록하는 것

이는 비기능적 요구사항에 해당함
-> 즉 사용자에게 필요한 기능은 아니지만 디버깅, 발생한 문제 해결 시에 원인을 분석하는데 필요한 요소

자바에서는 log4j 이후 출시된 LogBack을 사용하며 spring-boot-starter-web 라이브러리 내부에 내장돼 있어 별도의 의존성을 추가하지 않아도 됨

LogBack 특징

  1. 크게 5개의 로그 레벨(TRACE, DEBUG, INFO, WARN,ERROR)을 설정할 수 있다

  2. 실제 운영 환경 개발 환경에서 각각 다른 출력 레벨을 설정해서 로그 확인 가능

  3. LogBack의 설정 파일을 일정 시간마다 스캔해서 애플리케이션을 재가동하지 않아도 설정 변경 가능

  4. 별도의 프로그램 지원 없이도 자체적으로 로그 파일 압축 가능

  5. 저장된 로그 파일에 대한 보관 기간 등을 설정해서 관리 가능

Error : 로직 수행 중에 시스템에 심각한 문제가 발생해서 애플리케이션의 작동이 불가능한 경우

WARN : 시스템 에러의 원인이 될 수 있는 경고 레벨 의미

INFO : 애플리케이션의 상태 변경과 같은 정보 전달을 위해 사용

Debug : 애플리케이션의 디버깅을 위한 메세지를 표시하는 레벨을 의미

TRACE : 디버그 레벨보다 더 상세히 메세지를 표현하기 위한 레벨

LogBack 설정

우선 resources 폴더 안에 logback-spring.xml 파일을 추가합니다

log back 설정 파일 예시

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

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

    <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>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] %logger %msg%n</pattern>
        </encoder>
    </appender>

    <!-- Trace>Debug>INFO>WARN>ERROR>OFF -->
    <!-- Root Logger -->
    <root level = "INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="INFO_LOG"/>
    </root>
</configuration>

총 5가지 영역으로 구성되어 있음

  1. property 영역 2. Appender 영역 3. Encoder 영역 4. Pattern 영역 5. Root 영역

Appender 영역

로그의 형태를 설정하고 어떤 방법으로 출력할지 설정하는 곳

하나의 인터페이스이며, 하위에 여런 구현체 존재

ConsoleAppender : 콘솔에 로그 출력

FileAppender : 파일에 로그 저장

RollingFileAppender : 여러 개의 파일을 순회하면서 로그 저장

SMTPAppender : 메일로 로그 전송

DBAppender : 데이터베이스에 로그 저장

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

appender 요소의 class 속성에 각 구현체를 정의

filter 요소로 각 Appender어떤 레벨로 로그를 기록하는지 지정

encoder 요소를 통해 로그 표현 방식을 pattern으로 지정

  • %Logger{lengh} : 로거의 이름
  • -5level : 로그 레벨, -5는 출력 고정폭 값
  • %msg(%message) : 로그 메세지
  • %d : 로그 기록 시간
  • %p : 로깅 레벨
  • %F : 로깅이 발생한 애플리케이션 파일명
  • %M : 로깅이 발생한 메서드 이름
  • %I : 로깅이 발생한 호출지의 정보
  • %thread : 현재 스레드 명
  • %t : 로깅이 발생한 스레드명
  • %c : 로깅이 발생한 카테고리
  • %C : 로깅이 발생한 클래스명
  • %m : 로그 메세지
  • %n : 줄바꿈
  • %r : 애플리케이션 실행 후 로깅이 발생한 시점까지의 시간
  • %L : 로깅이 발생한 호출 지점의 라인 수

Root 영역

설정 파일에 정의된 Appender를 활용하려면 Root 영역에서 Appender를 참조 해서 로깅 레벨을 설정

특정 패키지에 대해 다른 로깅 레벨을 설정하고 싶다면 root 대신 logger사용해 지정

<root level = "info">
	<appender-ref ref="console"/>
    <appender-ref ref="INFO_LOG"/>
</root>
<logger name="com.springboot.api.controller" level="DEBUG" additivity="false">
	<appender-ref ref = "console"/>
    <appender-ref ref = "INFO_LOG"/>
</logger>

여기서 name요소에 패키지 단위로 로깅이 적용될 범위 지정하고 level 속성으로 로그 레벨 지정

additivity 속성은 앞에서 지정한 패키지 범위에 하위 패키지를 포함할지 여부 결정
기본값은 true : 하위 패키지 모두 포함


Logback 적용하기

logback-spring.xml

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

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

    <!-- Trace>Debug>INFO>WARN>ERROR>OFF -->
    <!-- Root Logger -->
    <root level = "INFO">
        <appender-ref ref="console"/>
    </root>
</configuration>
@RestController
@RequestMapping("/api/v1/get-api")
public class GetController {

    private final Logger LOGGER = LoggerFactory.getLogger(GetController.class);

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String getHello(){
        LOGGER.info("getHello 메서드가 호출되었습니다.");
        return "Hello world";
    }

    @GetMapping(value = "/name")
    public String getName(){
        LOGGER.info("getName 메서드가 호출되었습니다.");
        return "Flature";
    }
    

    @GetMapping(value = "/variable/{variable}")
    public String getVariable(@PathVariable String variable){
        LOGGER.info("@Pathvariable을 통해 들어 온 값: {}", variable);
        return variable;
    }
}
private final Logger LOGGER = LoggerFactory.getLogger(GetController.class)

Appender에게 전달할 Logger 객체를 각 클래스에서 정의하여 사용

LoggerFactory통해 객체를 생성하며 이때 클래스 이름을 함께 지정하여 클래스의 정보를 LOGGER에서 가져가게 함

LOGGER.info("getHello 메서드가 호출되었습니다.");
LOGGER.info("getName 메서드가 호출되었습니다.");
LOGGER.info("@Pathvariable을 통해 들어 온 값: {}", variable);

info 레벨의 로그 출력

위처럼 하였을 시 Swagger에서 테스트를 할때 각 메서드가 호출되면 콘솔창에 로그가 찍힘

[2022-22-26 13:22:27.085] [INFO ][http-nio-8080-exec-10] com.springboot.api.controller.GetController @Pathvariable을 통해 들어 온 값: hello

애플리케이션 마다 어떤 로그를 출력하는 것이 가장 이상적일지 상황에 맞게 고민해보자!!

profile
Journey for Backend Developer

0개의 댓글