Spring Projcect/날씨 일기 프로젝트

Chapter 08. 로그(log) 남기기

계란💕 2022. 9. 1. 13:05

8.1 Spring Boot Logging 이란?

 

log를 쓰는 이유

  • 서비스 동작 상태 파악
  • 장애 파악
    • System.out.print() => 출력 외에 부가 기능(오랜된 로그를 지우거나 로그를 파일에 저장하다거나 기능)이 없다.
    • Logging library 사용 => 실무에서 많이 사용한다.
      • ex)
        • log4f => log4j2
        • logback: log4f보다 기능이 많다

 

 

log level(로그 레벨)

  • Error: 즉시 조치를 취해야하는 심각한 경우에 발생한다.
  • Warn: 로직 상 유효성을 확인할 때, 쓰인다.
  • Info: 서비스를 운영하는데 중요한 작업이 끝나는 경우에 작성한다.
  • Debug: 개발 단계에서 많이 사용하고 위의 레벨들이 실제 파일에 로그를 저장하고 남기도록 설정한다.
  • Trace: 개발 단계에서 많이 사용하고 위의 레벨들이 실제 파일에 로그를 저장하고 남기도록 설정한다.

 

 

 

8.2 logback 사용하기

 

logback 사용하기

  • 새로운 라이브러리를 쓰려면 build.gradle에 추가하지만 log back은 스프링 부트에 내장되어 있어서 build에 추가할 필요 없다.
  • 아래와 같이 xml  파일을 만든다.
  • 세 개의 appender를 만든다.
  • pattern에 있는 형식대로 log가 저장된다.
  • RollingFileAppender - 롤링시키면서 로그를 저장한다.
    • ex) 기간을 열흘로 정하는 경우, 10일까지 로그를 저장하면 11일에는 1일의 로그를 지우고 11일의 로그를 저장한다.
<hide/>
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

<!--    로그가 쌓일 경로와 어떤 레벨의 로글를 쌓을 건지 설정(info 이상의 로그만)  -->
    <property name="LOGS_PATH" value="./logs"/>
    <property name="LOGS_LEVEL" value="INFO"/>

<!--    console appender - 콘솔에 출력될 log  설정 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{HH:mm} %-5level %logger{36} = %msg%n</pattern>
        </layout>
    </appender>

<!--    FILE appender - -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOGS_PATH}/log_file.log</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
<!--        Rolling 정책 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--           gz, zip 등을 넣으면 자동 일자별 로그파일을 압축한다.-->
            <fileNamePattern>${LOGS_PATH}/%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>60</maxHistory>
        </rollingPolicy>
    </appender>


    <!--    Error appender - -->
    <appender name="Error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOGS_PATH}/error_file.log</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- Rolling 정책 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            <!-- gz, zip 등을 넣으면 자동 일자별 로그 파일을 압축한다.-->
            <fileNamePattern>${LOGS_PATH}/%d{yyyy-MM-dd}_error.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
<!--        threshold filter를 넣어서 error 이상의 로그만 걸러지도록 한다.-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>

    <root level="${LOGS_LEVEL}">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="Error"/>
    </root>
</configuration>

 

  • application.propertires - 로그가 설정된 파일 이름을 저장한다.
logging.config=classpath: logback-spring.xml

 

 

  Note) 실행 결과

   - log라는 폴더가 새로 생긴다. 

    -> 에러가 없으면 error_file은 비어있다.

    -> log_file은 스프링 부트가 켜지면서 항상 발생한 로그가 쌓인걸 볼 수 있다.

 

 

 

  Ex) 로그를 지정해서 쌓아보자

 

  • 로거를 프로젝트 전체에 하나만 만들어서 프로젝트 전체에서 로거를 쓴다.
  • Service - createDiary()
<hide/>
@Transactional(isolation = Isolation.SERIALIZABLE)
public void createDiary(LocalDate date, String text){

    logger.info("== Started to create diary ==");
    // 날씨 데이터 가져오기
    DateWeather dateWeather = getDateWeather(date);

    // 파싱된 데이터와 일기 값을 내 데이터베이스에 넣기
    Diary nowDiary = new Diary();
    nowDiary.setDateWeather(dateWeather);
    nowDiary.setText(text);
    diaryRepository.save(nowDiary); // DB에 데이터 넣는다.
    logger.info("== End to create diary ==");
}

 

  • Service - readDiary()
<hide/>
@Transactional(isolation = Isolation.SERIALIZABLE)
public List<Diary> readDiary(LocalDate date) {
    logger.debug("== Read Diary ==");
    return  diaryRepository.findAllByDate(date);
}

 

 

  Note) createDiary 실행 결과 - log_file 에 들어가면 아래와 같이 나온다.

 

  • 주의사항
    • .gitignore에 logs를 추가한다.
    • 깃허브에는 소스 코드만 올린다.

 

 

 

출처 - 제로베이스 백엔드 스쿨 (김조현 강사님)

https://zero-base.co.kr/

 

제로베이스 - 누구나 취업하는 가장 합리적인 취업 스쿨

코딩 부트 캠프 개발자, 데이터 사이언티스트, 마케터, PM, 디자이너 등 제대로 공부하고 확실하게 취업하세요. 당신의 삶의 전환점이 될 제로베이스 스쿨입니다.

zero-base.co.kr