모니터링을 위한 AWS CloudWatch와 Logback.xml연동
AWS 클라우드 서비스를 운영하며 라이브 서비스시 개발자가 물리적인 서버 주변에 있지않아도 서버 장애가 발생시에 빠른 복구를 하기위해 실시간 모니터링을 할 수 있게 도와주는 AWS CloudWatch를 사용하여 서버 안정성을 향상시켰습니다.
프로젝트를 제작하며 어플리케이션 내부에서 Log4j2를 사용한 로깅을 설정하였습니다.
하지만 라이브 서비스 환경에서는 Log4j2만을 사용해서는 크리티컬한 에러(CPU 80% 이상, DBMS 연결 오류, 응답 지연 등)에 대해서 실시간으로 확인할 수 없었으며 이를 보완하기위해 설정한 이벤트가 발생시에 SMS를 통해 개발자에게 연락을 취할 수 있는 방법중 하나인 AWS CloudWatch를 연동하여 사용하게 되었습니다.
AWS CloudWatch
AWS(Amazon Web Service)에서 제공하는 모니터링 및 로깅 서비스로, AWS환경에서의 리소스 및 어플리케이션의 상태를 실시간으로 추적하고 관리할 수 있는 도구입니다.
- 특징 :
- 어플리케이션의 상태를 확인하며 메트릭 데이터와 로그를 수집하는 실시간 모니터링이 가능하다.
- 특정 이벤트가 발생하거나 지정한 조건이 충족되면 알림을 생성하여 사용자에게 신속한 대응이 가능하다.
- 사용자 정의 대시보드를 생성하여 모니터링하고자 하는 메트릭 데이터를 시각적으로 확인할 수 있다.
- Auto Scaling과 통합하여 어플리케이션의 자동 조정 및 스케일링을 지원한다.
- 장점 :
- 실시간으로 AWS환경의 상태를 모니터링하여 특정 이벤트에 대한 빠른 대응이 가능하다.
- Auto Scaling과 연동하여 인스턴스 EC2를 자동으로 확장 또는 축소할 수 있다.
- 대시보드를 통해 필요한 정보들을 시각적으로 확인할 수 있다.
- 지표,로그 분석을 통해 디버깅 속도를 높이고 발생한 이벤트에 대한 해결 시간을 단축가능하다.
- 단점 :
- CloudWatch를 사용시 데이터 로깅에 따른 비용이 있다.
[적용 과정]
AWS CloudWatch를 연동하기 위한 과정입니다.
해당 포스팅은 홈페이지 내 CloudWatch 이벤트 설정이 아닌 어플리케이션과 연동하여 로깅을 하는 과정이며
적용하기 전 해당 계정에 대한 AWS IAM KEY 생성 및 권한 설정을 요구합니다.
AWS IAM 이란?
- AWS 리소스에 대한 액세시를 안전하게 제어할 수 있도록 도와주는 웹 서비스
- AWS 계정에 대한 액세스를 요청하는 개별적인 사용자를 생성하며 각각의 별도의 역할을 부여 후 관리할 수 있다.
- 최소 권한의 원칙을 사용하여 AWS 계정의 보안성을 높이기위해 사용한다.
AWS IAM Key 생성방법 : https://docs.aws.amazon.com/ko_kr/keyspaces/latest/devguide/access.credentials.html#create.keypair
AWS IAM 권한 설정 :
build.gradle
dependencies {
implementation 'ca.pjer:logback-awslogs-appender:1.6.0'
}
AWS를 사용하기위한 의존성 주입을 합니다.
※ awslogs 라이브러리에는 log4j2 라이브러리가 포함되어 있어 기존의 spring-boot-starter-log4j2와는 라이브러리 충돌 (빌드시 illegalargumentexception accept 713) 이 발생합니다. 기존의 log4j2 라이브러리를 삭제해주세요.
application.properties
AWS_ACCESS_KEY=#####################
AWS_SECRET_KEY=#####################
AWS계정에서 생성한 IAM ACCESS KEY에 대한 정보를 설정합니다.
logback.xml
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="dailyRollingFileAppender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{HH:mm:ss.SSS} [%thread] [%5level] %logger{35}[%method:%line] %m%n</pattern>
</encoder>
</appender>
<appender name="dailyCloudwatchAppender"
class="ca.pjer.logback.AwsLogsAppender">
<layout>
<pattern>[%thread] [%date] [%level] [%file:%line] - %msg%n</pattern>
</layout>
<logGroupName>/aws/ec2/instance/cloudwatch-log-example/application-log</logGroupName>
<logStreamUuidPrefix>cloudwatch-log-example-</logStreamUuidPrefix>
<logRegion>ap-northeast-2</logRegion>
<maxBatchLogEvents>50</maxBatchLogEvents>
<maxFlushTimeMillis>30000</maxFlushTimeMillis>
<maxBlockTimeMillis>5000</maxBlockTimeMillis>
<retentionTimeDays>0</retentionTimeDays>
<accessKeyId>#################</accessKeyId>
<secretAccessKey>###############</secretAccessKey>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{HH:mm:ss.SSS} [%thread] [%5level] %logger{35}[%method:%line] %m%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="dailyRollingFileAppender"/>
<appender-ref ref="dailyCloudwatchAppender"/>
</root>
</configuration>
- <include resource>
- Spring Boot에서 기본적으로 제공하는 로깅 설정인 base.xml을 포함한다.
- <appender>
- TimeRollingPolicy : 시간을 기반으로 RollOver 정책을 정의한다.
- fileNamePattern : 기록할 로그 파일 제목의 포맷을 정의한다.
- maxHistory : 최대 몇일간 유지할 것인지 의 일 수를 정의한다.
- layout : 로그 파일에 작성될 포맷에 대한 정의를 한다.
- logGroupName : CloudWatch에 기록할 로그들을 그룹화 할 수 있게 도와준다.
- logStreamUuidPrefix : 로그 파일이 생성할 때 무작위 uuid가 생성이 되는데, 해당 uuid의 접두사를 설정할 때 사용한다. ex) cloudwatch-log-example-uuid(e59bd81b-d735-4f36-b484-38df94fd67b6)
- logRegion : IAM 사용자의 Region을 설정한다.
- maxBatchLogEvents : CloudWatch에 전송할 이벤트의 최대 수를 나타낸다. (1~10000)
- maxBlockTimeMillis : 로그 이벤트를 플러시하는데 최대로 차단되는 시간.
- retentionTimeDays : 로그 그룹의 보존 기간. 0일시 무제한
- accessKeyId,secretAccessKey : 로그를 전송할 IAM 계정의 Key를 입력한다.
[결과]
logStreamUuidPrefix -uuid 형태의 로그 스트림이 기록된다.
각각의 로그 스트림에 설정한 포맷 형태의 정보가 저장된다.
Amazon Simple Notification Service를 연동한 실시간 모니터링
개발자가 서버 운영시에 자리를 비운 상태인경우 클라우드 서비스의 상태를 확인하지 않는 이상 서버에서 어떤 장애들이 발생하였는지를 확인할 수 없었습니다. 이러한 경우 서버 장애가 발생시 빠른 복구를 하기위해 AWS에서 제공하는 SNS기능을 사용하여 AWS CloudWatch에서 경보들에 대한 알림을 설정하겠습니다.
1. Amazon SNS 주제 생성 및 구독하기
→ https://docs.aws.amazon.com/ko_kr/sns/latest/dg/sns-getting-started.html
AWS CloudWatch에서 설정한 각각의 경보들이 누구에게 보내야 할지, 어떤 내용을 보내야 할지 설정을 하기위해
주제 - 구독 설정을 합니다.
주제 (Topic)
구독 (Subcroption)
2. CloudWatch에서 생성한 경보에 대한 엔드포인트 설정하기
생성한 경보에 대한 엔드포인트를 설정합니다.
[결과]
Putty를 사용한 원격 서비스 중 AWS CloudWatch에서 설정한 CPU의 사용량이 특정 값이 이상인것을 모니터링으로 감지할 수 있습니다.
또한 설정한 엔드포인트의 E-mail에도 알림 서비스를 제공받을 수 있습니다.
[느낀점]
기존의 Log4j2에서 확인할 수 없던 실시간 모니터링을 AWS CloudWatch를 사용하여 실시간 모니터링이 추가됐습니다.
이로인해 기존의 로컬환경에서 개발할 시에도 Log4j2와 같이 로깅을 할 수 있으며 추가적으로 라이브 서비스시 실시간으로 로그를 분석할 수 있으며 또한 AWS홈페이지 에서 특정 계정에 대한 SMS 연동을 추가할 시 안전성을 향상시킬 수 있습니다.
출처 및 참고내역
https://ckddn9496.tistory.com/82