개발환경
- SpringBoot v3.3.3
- AWS EC2 (ubuntu)
- RDS
- Docker Compose
- GithubActions
로그를 파일로 저장하기(환경 분리 포함)
스프링부트에서 local 환경과 prod 환경을 분리하여 로그를 남기는 방법은 아래의 글에서 참고하였다.
https://blog.pium.life/server-logging/
이 글은 local 환경에서는 콘솔에서 로그를 확인할 수 있고 prod환경에선 info 로그와 error 로그 파일을 분리할 수 있는 설명이 담겨있다.
먼저 application.yml에서 프로필을 분리해주어야 한다.
- application-local.yml
spring:
config:
activate:
on-profile: local
- application-prod.yml
spring:
config:
activate:
on-profile: prod
이후 /src/main/resources 에 아래의 파일을 정의한다.
이 파일들은 로그 내용을 파일로 저장할 때 쓰는 파일이다.(Logback)
- console-appender.xml
<included>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
</included>
- file-info-appender.xml
<included>
<appender name="FILE-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>./log/info-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
</appender>
</included>
- file-error-appender.xml
<included>
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>./log/error-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
</appender>
</included>
- logback-spring.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %clr(%5level) %cyan(%logger) - %msg%n"/>
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5level %logger - %msg%n"/>
<!--local-->
<springProfile name="local">
<include resource="console-appender.xml"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<!--prod-->
<springProfile name="prod">
<include resource="file-info-appender.xml"/>
<include resource="file-error-appender.xml"/>
<root level="INFO">
<appender-ref ref="FILE-INFO"/>
<appender-ref ref="FILE-ERROR"/>
</root>
</springProfile>
</configuration>
이렇게 설정하면 local 환경에서는 콘솔로 로그를 확인할 수 있고, prod 환경에서는 ./log 폴더에 날짜별로 info와 error 로그 내용을 저장할 수 있다.
날짜 뒤에 숫자는 같은 날짜의 로그파일을 구분하는 숫자이고, 로그 파일이 50MB를 넘었을 때 새로운 파일에 로그를 저장하고 숫자가 1 증가하여 저장된다.
- 예를들어 error-2024-10-11.0.log의 파일 용량이 50mb가 넘었을 시에 error-2024-10-11.1.log이 생성되고 여기에 로그를 마저 저장하는 것이다.
또한 error-2024-10-11.0.log의 파일 용량이 50mb가 넘었을경우 gz라는 확장자로 압축하여 저장하게 된다.
이를 통해 로그 파일의 용량을 최소화하여 저장할 수 있다.
마지막으로 error를 저장하는 로그와 info를 저장하는 로그 파일 각각 60개가 넘었을 시에 가장 오래된 로그파일을 삭제하도록 되어있다.
이 로그파일은 ./log 폴더에 저장되는데 내 프로젝트는 도커 환경에서 실행되므로 도커 볼륨을 통하여 도커 컨테이너 외부에 저장할 필요가 있다.
Docker Volume 을 이용하여 로그파일을 컨테이너 외부에 저장
먼저 dockerfile은 아래와 같다.
- dockerfile
# 베이스 이미지로 OpenJDK 17 사용
FROM openjdk:17-jdk
# 애플리케이션을 위한 작업 디렉토리 설정
WORKDIR /spring-boot
# 빌드된 JAR 파일을 컨테이너로 복사
COPY build/libs/*SNAPSHOT.jar promise.jar
# 애플리케이션 실행
ENTRYPOINT ["java", "-jar", "/spring-boot/promise.jar"]
WORKDIR 이 /spring-boot로 설정되어있다.
그래서 log 폴더는 컨테이너 내부의 spring-boot/log에 생성된다.
- compose.yml
services:
...
volumes:
- /home/ubuntu/promise/log:/spring-boot/log
...
이 옵션을 통해서 컨테이너에 존재하고 있던 log 폴더를 외부로 빼낼 수 있다.
즉, 도커 컨테이너 내부의 spring-boot/log 폴더를 ec2 인스턴스의 /home/ubuntu/promise/log 폴더와 공유하게 된다.
이렇게 하면 도커 컨테이너가 종료되거나 삭제되어도 로그 파일을 유지할 수 있다.
'Cloud > Docker' 카테고리의 다른 글
[Docker] 애플리케이션 종료시 Compose 자동시작 (1) | 2024.10.13 |
---|---|
[Docker + SpringBoot] Docker와 SpringBoot의 타임존 동기화 (1) | 2024.10.09 |
[Docker] Stateless 와 Volume (1) | 2024.09.12 |
[Docker] 도커 네트워크 (0) | 2024.09.11 |
[Docker] 이미지와 컨테이너 레이어 (0) | 2024.09.09 |