Spring Boot와 Logback을 사용한 효과적인 로깅 설정

바움핀테크·2024년 7월 16일
post-thumbnail

안녕하세요. 비유바움의 Miss 정 입니다!
오늘은 Spring Boot 애플리케이션에서 Logback을 사용하여 효과적으로 로깅을 설정하는 방법에 대해 알아보겠습니다. 로깅은 애플리케이션의 상태를 모니터링하고 문제를 해결하는 데 매우 중요한 역할을 합니다. Spring Boot와 Logback의 조합을 통해 강력하고 유연한 로깅 시스템을 구성할 수 있습니다.

1. Logback 이란?

Logback은 Java 애플리케이션을 위한 로그 프레임워크로, 빠르고 유연하며 설정이 간단합니다. 또한 SLF4J(Simple Logging Facade for Java)를 통해 다양한 로깅 프레임워크와 호환됩니다.

Logback은 logback-core, logback-classic, logback-access 세 가지 모듈로 구성되어 있습니다.

  • logback-core: 두 모듈의 기반이 되는 모듈로, appender와 layout 인터페이스를 포함합니다.
  • logback-classic: logback-core에서 확장된 모듈로, SLF4J API 라이브러리를 포함하며 Logger 클래스를 포함합니다.
  • logback-access: Servlet Container와 통합되어 Http Access에 대한 로깅 기능을 제공합니다.

2. Spring Boot에서 Logback 설정하기

Spring Boot 애플리케이션에서는 기본적으로 src/main/resources 경로에 logback-spring.xml 파일을 생성하여 Logback 설정을 관리할 수 있습니다.


3. 환경별 로깅 설정

Spring Boot의 프로파일 기능을 활용하여 개발, 테스트, 운영 환경별로 다른 로깅 설정을 적용할 수 있습니다. logback-spring.xml 파일을 다음과 같이 수정하여 환경별 설정을 추가할 수 있습니다.

<?xml version="1.0" encoding="UTF-8"?>

<!-- 1초마다 설정 파일 변경 감지 -->
<configuration scan="true" scanPeriod="1 seconds">

    <!-- local profile -->
    <springProfile name="local">

        <!-- 콘솔 -->
        <appender class="ch.qos.logback.core.ConsoleAppender" name="console">
            <encoder>
                <charset>UTF-8</charset>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%X{traceId}] %msg \(%logger:%+3line\)%n</pattern>
            </encoder>
        </appender>

        <root level="info">
            <appender-ref ref="console"/>
        </root>

        <logger level="off" name="p6spy"/>

    </springProfile>


    <!-- dev profile -->
    <springProfile name="dev">

        <!-- 콘솔 -->
        <appender class="ch.qos.logback.core.ConsoleAppender" name="console">
            <encoder>
                <charset>UTF-8</charset>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%X{traceId}] %msg \(%logger:%+3line\)%n</pattern>
            </encoder>
        </appender>

        <logger level="off" name="p6spy"/>

        <root level="info">
            <appender-ref ref="console"/>
        </root>

    </springProfile>


    <!-- prod profile -->
    <springProfile name="prod">

        <!-- 콘솔 -->
        <appender class="ch.qos.logback.core.ConsoleAppender" name="console">
            <encoder>
                <charset>UTF-8</charset>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%X{traceId}] %msg \(%logger:%+3line\)%n</pattern>
            </encoder>
        </appender>

        <logger level="off" name="p6spy"/>

        <root level="info">
            <appender-ref ref="console"/>
        </root>

    </springProfile>

</configuration>

위와 같이 springProfile을 통해 개발 환경에 따라 로그 관리를 구분 지을 수 있으며 필요한 appender를 추가할 수 있습니다.

  • springProfile
    환경에 따른 복수 개의 프로파일을 설정할 수 있습니다.
    설정한 name은 SPRING_PROFILES_ACTIVE에 따라 결정됩니다.

  • appender
    로그의 형태를 설정하고 로그 메시지가 출력될 대상을 결정할 수 있습니다.

  • encoder
    로그 메시지의 형식을 정의합니다.

  • pattern
    %Logger{length} : Logger name을 축약. {length}는 최대 자리 수
    %-5level : 로그 레벨, -5는 출력의 고정폭 값(5글자)
    %msg : - 로그 메시지
    ${PID:-} : 프로세스 아이디
    %d : 로그 기록 시간
    %p : 로깅 레벨
    %F : 로깅이 발생한 프로그램 파일명
    %M : 로깅일 발생한 메서드의 명
    %l : 로깅이 발생한 호출지의 정보
    %L : 로깅이 발생한 호출지의 라인 수
    %thread : 현재 Thread 명
    %t : 로깅이 발생한 Thread 명
    %c : 로깅이 발생한 카테고리
    %C : 로깅이 발생한 클래스 명
    %m : 로그 메시지
    %n : 줄바꿈(new line)
    %% : %를 출력
    %r : 애플리케이션 시작 이후부터 로깅이 발생한 시점까지의 시간(ms)

  • root, logger
    설정한 appender를 참조하여 package와 level을 설정할 수 있습니다.
    root : 전역 설정
    logger : 지역 설정


4. AWS CloudWatch와 Slack 연동

운영 환경에서 로그를 중앙에서 관리하고 알림을 받기 위해 AWS CloudWatch와 Slack을 연동할 수 있습니다.

cloud watch를 사용하기 위해 의존성을 추가합니다.

implementation("ca.pjer:logback-awslogs-appender:1.6.0")

다음은 logback-spring.xml 파일에 추가된 AWS CloudWatch 설정입니다.

<!-- prod profile -->
<springProfile name="prod">

    ...

    <!-- 로그 스트림 -->
    <appender class="ca.pjer.logback.AwsLogsAppender" name="aws_cloud_watch_log">
        <layout>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%X{traceId}] %msg \(%logger:%+3line\)%n</pattern>
        </layout>

        <logGroupName>/fintech/log</logGroupName>
        <logStreamUuidPrefix>log-</logStreamUuidPrefix>
        <logRegion>ap-northeast-2</logRegion>
        <maxBatchLogEvents>50</maxBatchLogEvents>
        <maxFlushTimeMillis>30000</maxFlushTimeMillis>
        <maxBlockTimeMillis>5000</maxBlockTimeMillis>
        <retentionTimeDays>0</retentionTimeDays>
        <accessKeyId>${AWS_ACCESSKEY}</accessKeyId>
        <secretAccessKey>${AWS_SECRET_ACCESSKEY}</secretAccessKey>
    </appender>

    <root level="info">
        ...
        <appender-ref ref="aws_cloud_watch_log"/>
    </root>

    ...

</springProfile>

AWS CloudWatch에 로그를 기록하기 위해 appender를 추가합니다.

  • layout
    encoder와 마찬가지로 로그의 출력 포맷을 지정합니다.

  • logGroupName
    AWS CloudWatch Logs의 로그 그룹 이름입니다.

  • logStreamUuidPrefix
    로그 스트림 이름에 사용할 접두사입니다.
    각 로그 스트림 이름은 이 접두사와 UUID를 조합하여 생성됩니다.

  • logRegion
    로그를 전송할 AWS 리전입니다.

  • maxBatchLogEvents
    한 번에 전송할 최대 로그 이벤트 수입니다. (기본값은 50)

  • maxFlushTimeMillis
    로그 이벤트 배치가 전송되기 전, 최대 대기 시간(밀리초)을 지정합니다. (기본값 30,000 밀리초)
    즉, 로그 이벤트가 쌓여있더라도 30초가 지나면 해당 로그 이벤트들이 전송됩니다.

  • maxBlockTimeMillis
    배치 작업을 하기 전, 내부 버퍼가 가득 찼을 때 기다리는 시간(밀리초)을 지정합니다. (기본값 5,000 밀리초)

  • retentionTimeDays
    로그의 보관 기간입니다. (기본값 0 : AWS의 보관 정책에 따름)

  • accessKeyId
    AWS Access Key로 환경 변수나 다른 외부 설정에서 제공되어야 합니다.

  • secretAccessKey
    AWS Secret Key로 환경 변수나 다른 외부 설정에서 제공되어야 합니다.


Slack 채널에 로그를 전송하기 위해 의존성을 추가합니다.

implementation("com.github.maricn:logback-slack-appender:1.6.1")
implementation("net.gpedro.integrations.slack:slack-webhook:1.4.0")

다음은 logback-spring.xml 파일에 추가된 Slack 설정입니다.

<!-- prod profile -->
<springProfile name="prod">

    ...

    <!-- 슬랙 -->
    <appender class="com.github.maricn.logback.SlackAppender" name="slack">
        <webhookUri>${SLACK_WEBHOOK_URI}</webhookUri>
        <channel>#finit</channel>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%X{traceId}] %msg \(%logger:%+3line\)%n</pattern>
        </layout>
        <username>핀잇-봇</username>
    </appender>
    <appender class="ch.qos.logback.classic.AsyncAppender" name="slack_async">
        <appender-ref ref="slack"/>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>

    <root level="info">
        ...
        <appender-ref ref="slack_async"/>
    </root>

    ...

</springProfile>

Slack 채널에 로그를 전송하기 위해 appender를 추가합니다.

  • webhookUri
    로그를 전송할 URL이며, Slack에서 제공합니다.

  • channel
    로그를 전송할 채널 이름을 지정합니다.

  • username
    Slack 메시지에 표시될 사용자 이름을 지정합니다.

  • ch.qos.logback.classic.AsyncAppender
    AsyncAppender를 사용하여 비동기적으로 로그를 처리합니다.
    appender-ref : 앞서 정의한 slack appender를 참조합니다.

  • ch.qos.logback.classic.filter.ThresholdFilter
    특정 로그 레벨 이상의 로그만을 허용하도록 지정할 수 있습니다.


Spring Boot와 Logback을 사용하면 애플리케이션의 로깅을 효과적으로 관리할 수 있습니다. 환경별로 다른 설정을 적용하고, AWS CloudWatch와 Slack과 같은 외부 서비스와 연동하여 로그를 중앙에서 관리하고 알림을 받을 수 있습니다. 이를 통해 애플리케이션의 상태를 모니터링하고, 문제를 신속하게 해결할 수 있습니다.

이상으로 Spring Boot와 Logback을 사용한 효과적인 로깅 설정 방법에 대해 알아보았습니다. 감사합니다!

profile
항상 새로움과 혁신을 추구하는 바움 핀테크팀 입니다!

0개의 댓글