스프링 로깅 실전편

김파란·2025년 1월 19일

project

목록 보기
9/9
post-thumbnail

개요

  • 서비스가 실행되면 여러가지 정보들을 로그에 남긴다
  • 아무런 설정을 하지 않으면 파일에 남지 않고 콘솔에만 남고있다
  • 로그가 문제해결에 활용되기 위해서는 애플리케이션이 실행되고 나서 시간이 지난 후에도 남아야 한다
    • 파일, 콘솔, DB의 형태로 남길 수 있다

Lobgack 설정

  • application.yml 로도 설정이 가능하지만, 로그백 설정만 따로 분리해서 관리하기 위해 별도의 파일을 작성하는게 좋다고 한다
  • resources에 logback-prod.xml식으로 만들면 된다
    • application.yml처럼 뒤에 -dev, -prod식으로 만들면 된다

스프링 부트에서 로그백을 사용하기 위해서 다음과 같은 파일들을 로드해서 한다

  1. logback-spring.xml
  2. logback-spring.groovy
  3. logback.xml
  4. logback.groovy
  • 클래스 경로의 파일에 다음 이름 중 하나가 있으면 Spring Boot 는 자동으로 기본 구성 위에 파일을 로드합니다.
  • 💡 logback vs logback-spring
    스프링 공식문서를 살펴보면 가능하다면 표준보다 "-spring" 을 붙여서 사용하는걸 추천한다고 한다
    • 표준 버전 즉, logback.xml 을 사용한다면 Spring 이 완벽하게 로그 초기화를 제어하지 못한다고 합니다.
    • 아마도, logback.xml 파일은 너무 빨리 로드되기 때문에, 이 파일 안에선 Extensions을 사용할 수 없다고하는데 이 때문인 것 같다.

설정파일

  • configuraiton이라는 최상단 루트를 가지고 있다
    • 그 아래에는 property, appender, root가 있다
  • property는 파일내에서 사용할 변수를 지정한다
  • appender가 핵심적인 내용으로 로그가 콘솔일지, 파일일지 그외에 다른 무언가로 할지 설정할 수 있는데 이를 설정할 수 있다
    • 다양한 종류의 appender가 있다
    • appender의 포맷에 따라 어떻게 보일지가 결정된다
  • root는 위에 정의된 appender 중에서 어떤 레벨의 로그가 해당 appender를 통해 기록될지 지정한다.
<configuration>
  	<!-- 환경 설정, 파일내에서 사용할 변수-->
    <!-- LOG_FILE이라는 키로 application.log 이름을 밸류로 잡고 만들겠다-->
    <property name="LOG_FILE" value="application.log"/>

    <!-- 콘솔 출력 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 파일 출력 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <!-- 환경 설정 LogFile 사용-->
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>application.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- Logger 설정 -->
   <!-- 현재는 info레벨 이상인 것들을 로그로 보여주겠다는 뜻이다 -->
    <root level="info">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

Appender

  • Logback은 다양한 종류의 Appender를 제공하며 대표적으로 콘솔, 파일, 네트워크, 데이터베이스가 있다

1. ConsoleAppender

  • 콘솔에 로그를 출력한다
    • 인텔리제이에서 터미널이라는 창에 로그를 찍는다
  • Encoder부분에 pattern으로 어떤 형태로 로그를 남길 지 형식을 지정할 수 있다
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

2. FileAppender

  • 지정된 파일에 로그를 기록한다
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  	<file>logs/app.log</file>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

3. RollingFileAppender

  • 로그 파일을 자동으로 롤링(분할)하여 관리한다
  • 파일을 작성할 때 RolllingPolicy로 분할정책을 지정할 수 있다
    • 보관 기간, 파일 이름 패턴등을 지정할 수 있다
    • 만약 <fileNamePattern>application.%d{yyyy-MM-dd}.log</fileNamePattern>dd 즉 일단위로 끝나면 maxHistory 단위도 일단위가 된다
    • <fileNamePattern>application.%d{yyyy-MM-dd_HH-mm}.log</fileNamePattern> 이런식으로 분까지 지정하면 maxHistory도 분단위가 된다
  • 압축: gz만 붙이면 gz파일형태로 압축이 된다 <fileNamePattern>application.%d{yyyy-MM-dd_HH-mm}.log.gz</fileNamePattern>

Filer과 RollingFile의 차이점

  • File
    • 로그를 하나의 파일에 계속해서 기록한다.
    • 용량 제한이나 파일 분할 기능이 없다
    • 파일 크기가 너무 커질 수 있으므로, 대용량 로그 관리에는 적합하지 않다.
  • RollingFile
    • 로그 파일이 특정 용량 또는 조건(예: 날짜) 이상이 되면 파일을 분할해서 저장한다
    • 분할 조건을 설정할 수 있습니다:
      • 크기 기반 분할: 로그 파일이 설정한 크기를 초과하면 새 파일로 분할한다
      • 시간 기반 분할: 일정 주기(예: 하루, 시간별)로 새 파일을 생성한다
    • 파일 관리가 용이하며, 대용량 로그 처리에 적합하다
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  	<file>logs/app.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>application.%d{yyyy-MM-dd}.log</fileNamePattern>
        <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

4. AsyncAppender

  • Logback도 비동기적으로 처리하지만 AsyncAppender를 쓰면 더욱 성능을 향상시킨다
  • 주요 옵션
    • queueSize: 비동기 큐의 크기
    • discardingThreshold: 큐가 가득찰 때 버릴 로그 수
<appender name="ASYNC" class="ch.qos.logback.core.AsyncAppender">
  <appender-ref ref="FILE" />
  <queueSize>513</queueSize>
  <discardingThreshold>0</discardingThreshold>
</appender>

그외의 Appender들

  • SyslogAppender: 시스템 로그로 로그를 전송한다
    • OS와 상호작용으로 로그를 OS에 있는 시스템 로그로 전송한다
  • SocketAppender: 소켓을 통해 로그를 원격 서버로 전송한다
    • 외부 서버나 다른 포트에 있는 프로그램으로 전송한다
  • SMTPAppender: 이메일을 통해 로그를 전송한다
  • DBAppender: 데이터베이스에 로그를 전송한다
  • CustomAppender: 사용자 정의 Appender를 만들어 특정 요구사항에 맞게 로그를 처리할수 있다

Profile설정

  • application에 설정하는 방법과 logback.xml에 설정하는 두가지 방법이 있다
  • logback.xml보다 application이 우선순위가 높기 때문에 application에 있는 정보로 설정된다
  • 첫번째 방법: applicaiton에 설정
    • logging.config=classpath:logback-dev.xml으로 설정해주면 된다
    • classpath은 프로젝트내에 resources경로를 나타내는 말이다
    • 이럴때는 기본 logback.xml은 없어야 한다
  • 두번째 방법: logback.xml에 설정
    • 기본 logback.xml로 application의 profile에 따라 설정해줄 수 있다
<configuration>
    <springProfile name="dev">
        <include resource="logback-dev.xml" />
    </springProfile>

    <springProfile name="prod">
        <include resource="logback-prod.xml" />
    </springProfile>

    <!-- Default fallback-->
    <springProfile name="default">
        <include resource="logback-dev.xml" />
    </springProfile>
</configuration>

ELK

  • File을 ElasticSearch로 이동하는것도 가능하지만, Logstash로 하는 것이 간편하다
  • 현재는 파일에도 남기고 ElasticSearch에도 저장을 시킨다
  • 극단적으로 ElasticSearch로 바로 로그를 이동시키는 방법도 있다

LogStash

  • LogStash 라이브러리를 추가하고 설정파일을 설정해주면 된다
  • LogStash는 자동으로 Json포맷으로 변환해주기 때문에 그대로 보내주면 Json으로 저장이된다
<!-- Logstash로 전송할 Appender -->
    <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>localhost:5044</destination>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

참고) https://livenow14.tistory.com/64

0개의 댓글