일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- virtualization
- 스프링
- mysql
- 백엔드
- CS
- JPA
- 가상화
- 스프링 부트
- 컨테이너
- spring batch
- Java
- 배포
- Spring
- 웹 서버
- Spring Security
- ORM
- 자바
- spring cloud
- 데이터베이스
- spring boot
- Container
- CI/CD
- 도커
- 스프링 배치
- computer science
- web server
- 영속성 컨텍스트
- 스프링 시큐리티
- HTTP
- vm
- Today
- Total
개발 일기
[Spring Boot] 스프링 프로젝트에 로깅 적용하기 본문
이전 게시글에서 로그 레벨까지 알아봤고 이제 실제 EC2에서 돌아가고 있는 스프링 컨테이너는 로깅이 어려웠기 때문에 로깅을 할 수 있도록 로깅 프레임워크를 적용 후에 컨테이너를 갈아 끼울 예정이다.
Logback에 대해
Logback을 사용할때 application.yml을 통해서 설정이 가능하지만 디테일한 설정을 하는데에는 한계가 있다. 그래서 logback-spring.xml을 통해 조금 더세부적인 설정이 가능하다. logback-spring.xml / logback-spring.groovy / logback.xml / logback.groovy의 이름을 한 파일을 스캔하고 이를 바탕으로 로그 설정이 적용된다. 이때 logback-spring.xml이 Spring Boot에 특화된 설정 파일이였다.
Appender, Logger, Layout 이렇게 크게 3가지로 나눌 수 있다.
첫번째로 Logger은 로깅을 수행하는 주요 객체이다. 로거는 이름을 가지며 주로 패키지 이름 또는 클래스 이름과 일치하게 설정한다.
Appender는 로깅 이벤트를 특정 출력 대상으로 전송하는 구성 요소이다.
로그 메시지가 추력될 대상을 결정하는 것이다. 각 로거는 하나 이상의 Appender에 연결될 수 있다.
- ConsoleAppender: 로그 메시지를 표준 출력(콘솔)에 기록
- FileAppender: 로그 메시지를 지정된 파일에 기록. 즉, 디스크에 영구적으로 저장
- RollingFileAppender
: 파일이 일정한 조건에 도달했을 때 새로운 파일로 로그를 기록하도록 한다. 이전의 로그 파일은 그대로 저장되며 하나의 로그파일이 너무 커지는 것을 방지한다.
- 특정 크기를 넘어가면 다음 로그파일로 넘어가고 이전의 로그파일이 특정 기간을 넘기면 삭제되고 이러한 설정들이 이뤄진다.
마지막으로 Layout이다. 이는 로깅 이벤트가 어떻게 formatting되어서 출력될지 결정하는 구성 요소이다. 사용자가 지정한 형식으로 로그 메시지를 변환하여 출력할 수 있다.
Logback 적용
현재 나는 로컬환경, 배포(운영) 환경 이렇게 2가지로 나누어서 작업 중이다. 그러나 보통은 로컬, 개발, 운영 이렇게 3가지로 한다.
로컬 서버는 SQL 쿼리확인 및 에러 그리고 DEBUG 수준의 로그를 확인해야한다.
개발 서버는 쿼리 확인, 의도한 예외가 발생하는 지에 대한 로그가 필요하다.
운영 서버에서는 쿼리나 의도한 예외를 확인하는 로그가 아니라 예상치 못한 NPE, ISE 등에 에러 로그가 필요하다.
이때 중요한 것은 개발, 운영 서버에서는 콘솔이 아니라 별도의 파일에 로그를 저장해야한다.
이렇게 각 환경마다 로그 전략이 다르다는 것을 확인할 수 있다.
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- org.springframework.boot.logging.logback.ColorConverter 클래스를 사용하여 ANSI 색상 변환을 위한 conversionRule 설정 -->
<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" />
<!-- 콘솔에 로그를 출력하는 ConsoleAppender 설정 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 콘솔 로그에 적용될 패턴 설정 -->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 파일에 로그를 출력하는 RollingFileAppender 설정 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<!-- 파일 로그에 적용될 패턴 설정 -->
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<!-- 로그 파일 롤링 정책 설정 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 로그 파일 이름 패턴 설정 -->
<fileNamePattern>./log/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 로그 파일의 최대 크기 설정 -->
<maxFileSize>100MB</maxFileSize>
<!-- 유지할 로그 파일의 최대 기간 설정 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!-- 로컬 프로파일 설정 -->
<springProfile name="local">
<!-- com.feelcoding.logbackdemo 패키지의 로그 레벨을 DEBUG로 설정 -->
<logger name="com.feelcoding.logbackdemo" level="DEBUG" />
<!-- 루트 로거 레벨을 DEBUG로 설정하고 CONSOLE appender에 참조 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
<!-- 개발 및 스테이징 프로파일 설정 -->
<springProfile name="dev|stg">
<!-- 루트 로거 레벨을 INFO로 설정하고 CONSOLE, FILE appender에 참조 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</springProfile>
<!-- 프로덕션 프로파일 설정 -->
<springProfile name="prod">
<!-- 루트 로거 레벨을 ERROR로 설정하고 CONSOLE, FILE appender에 참조 -->
<root level="WARN">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</springProfile>
</configuration>
나는 다음과 같이 설정했다.
컨테이너 안에?? 로그 파일을 어디 남기지?
그러나 갑자기 문득 의문이 생겼다. 로컬은 콘솔에 찍어서 상관없는데 운영 서버의 경우 로그 파일이 남는데 나는 도커 컨테이너를 통해 서버를 돌리기 때문에 도커 컨테이너 안에 로그 파일이 저장되는 것이다.
- 그렇게 되면 조회할때마다 remote ssh로 접속해서 docker exec로 들어와서 매번 콘솔창을 통해 조회해야해서 매우 불편할 것이다.
- 또한 도커 이미지는 읽기 전용이고 도커 켄테이너는 쓰기 가능인데 기존 이미지에서 변경된 사항을 컨테이너에 저장시킨다. 그러나 이때 컨테이너가 죽으면? 그 컨테이너 레벨에 있던 로그 파일 모두 삭제되게 된다. 그래서 파일을 영속적으로 저장시킬 필요가 있다.
그래서 고민을 해봤는데 도컬 볼륨을 사용하여 로그 파일을 Host인 EC2환경에 남기는 방법이다.
그래서 컴포즈 파일에 다음과 같이 볼륨 마운팅을 설정해줬다. 볼륨 마운팅(Volume Mounting)은 호스트 시스템의 디렉토리를 컨테이너 내부의 디렉토리에 연결했고 이것은 컨테이너가 종료되더라도 데이터를 유지하거나 컨테이너 간에 데이터를 공유하는 데 사용된다.
즉, 호스트인 EC2의 /home/ubuntu/workspace/logs 디렉토리를 컨테이너 내부의 /log 디렉토리에 마운트한다. 그래서 오른쪽과같이 /log에 쌓이는 로그들이 EC2 서버의 해당 경로와 연결되어 컨테이너가 죽더라도 컨테이너 내부의 데이터는 다 없어지지만 EC2 호스트에는 남아있게 된 것이다.
그래서 이제 ERROR 로그가 EC2 호스트의 지정해둔 파일 경로에 쌓이게 돼서 쉽게 로깅할 수 있게 됐다.
'Back-End > Spring' 카테고리의 다른 글
[Spring Boot] ModelMapper와 MapStruct (0) | 2024.05.31 |
---|---|
[Spring Boot] 예외 처리(Exception Handling) Reference (0) | 2024.05.27 |
[Spring Boot] 로깅 레벨(Logging Level) 정리 (0) | 2024.05.27 |
[Spring Security] OAuth2.0 + JWT 토큰 기반 인증 인가 (0) | 2024.05.13 |
[Spring Security] Spring Security Authentication Architecture (0) | 2024.05.03 |