💡 발단
앱을 런칭하기 전부터 불안한 점이 있었다.
"만약 서버가 터진다면... 어떻게 해결하지?".
그래서 생각한게 로깅이었다.
로깅이 모든 문제를 해결할 수는 없겠지만, 문제를 해결하는데 필요한 결정적인 실마리를 줄 수 있다고 생각했다.
적어도 비정상적인 요청 혹은 서버내의 에러를 파악할 수 있다고 생각해서 바로 적용하게 됐다.
물론 서버에 SSH 접속해서 직접 로그를 확인하는 방법도 있다.
그래서 해당 프로젝트에선 docker를 사용해서, docker log 명령어를 사용해서 확인해왔다.
그러나 만약 서버가 죽는다면?
SSH 접속 자체가 안된다면 원인을 파악할 방법이 없어지게 된다.
외부의 어딘가에 로그들을 저장해둘 필요가 있었다.
그래서 찾아본게 AWS CloudWatch.
공식적으로 로그 기능을 지원한다.
요금도 무료다. (tail 버튼은 누르지 말자. 실시간 업데이트를 해주는 기능인데 과금 요소다.)
🛠 로깅 설정 과정
CloudWatch 로그 그룹 생성
IAM에 CloudWatch 권한 추가 -> CloudWatch의 로그 그룹 탭 -> 로그 그룹 생성
그리고 AWS의 설정 정보를 이제 작성할 logback.xml에 넣으면 된다.
필자는 S3를 설정하면서 application.yml에 작성해둔 정보를 그대로 사용했다.
logback.xml 설정
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<property name="LOG_PATTERN"
value="${LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss}}:%-4relative) %highlight(%-5level) %clr(${PID:- }){magenta} %green(%thread) %boldWhite([%cyan(%C).%M:%yellow(%L)]) %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="AWS_LOG_PATTERN"
value="%date [%level] [%thread] [%file:%line] - %msg%n"/>
<springProperty name="AWS_REGION" source="cloud.aws.region.static"/>
<springProperty name="AWS_ACCESS_KEY" source="cloud.aws.credentials.access-key"/>
<springProperty name="AWS_SECRET_KEY" source="cloud.aws.credentials.secret-key"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_PATTERN}</Pattern>
</layout>
</appender>
<appender name="AWS_CLOUD_WATCH_LOG" class="ca.pjer.logback.AwsLogsAppender">
<layout>
<pattern>${AWS_LOG_PATTERN}</pattern>
</layout>
<logGroupName>bokjak-log</logGroupName>
<logStreamUuidPrefix>bokjak-log-</logStreamUuidPrefix>
<logRegion>${AWS_REGION}</logRegion>
<maxBatchLogEvents>50</maxBatchLogEvents>
<maxFlushTimeMillis>30000</maxFlushTimeMillis>
<maxBlockTimeMillis>5000</maxBlockTimeMillis>
<retentionTimeDays>0</retentionTimeDays>
<accessKeyId>${AWS_ACCESS_KEY}</accessKeyId>
<secretAccessKey>${AWS_SECRET_KEY}</secretAccessKey>
</appender>
<springProfile name="!prod">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="AWS_CLOUD_WATCH_LOG"/>
</root>
</springProfile>
</configuration>
위 파일에서 중요하게 볼 키워드는 appender, springProfile이다.
springProfile에서는 분리된 프로파일을 적용했다. prod는 실 운영서버의 프로파일명. !prod는 그 외의 프로파일.
이왕 로깅을 설정하는 김에 로그 레벨(INFO, WARN, ...)별로 다른 색깔을 줘봤다.
CloudWatch에는 그저 흑백 글씨만 남게 되어서 아쉽긴 했다. 그래도 이게 어디야.
개선할 점
Cloud Watch agent를 이용하면 메모리, 디스크 사용률을 확인할 수 있다고 한다.
궁금해진다.
'Back-end > Spring Boot' 카테고리의 다른 글
@ConfigurationProperites 이용한 프로퍼티 객체 관리 (0) | 2024.01.13 |
---|---|
[Spring JPA] 페이지네이션 일대다 FETCH JOIN 문제와 default_batch_size (0) | 2023.09.25 |
[Spring JPA] 엔티티 컬렉션 필드를 초기화해야 하는 이유 (0) | 2023.09.18 |
[Spring Boot] 커서 페이징(no offset)에서 Page 대신 Slice 사용하기 (1) | 2023.09.11 |
[Spring JPA] Hibernate에서 지원하지 않는 MySQL 랜덤 함수 직접 만들기 + Expressions 파헤쳐보기 (0) | 2023.09.06 |