Amazon Web Services 한국 블로그

Amazon CloudWatch 맞춤형 지표 생성하기

Amazon CloudWatch는 AWS 클라우드 리소스와 AWS에서 실행되는 어플리케이션을 위한 모니터링 서비스입니다. 게임 개발자나 시스템 운영자가 서비스를 관리하기 위해서는 필수적으로 CloudWatch를 사용해서 여러 서비스나 어플리케이션의 지표(metric)를 확인해야 합니다.

CloudWatch는 사용자의 편의를 위해서 전체 AWS 서비스에 대해 총 300개가 넘는 기본(Built-in) 지표를 제공합니다. 예를 들어, EC2나 RDS의 CPU 사용률이나 네트워크 트리팩 인/아웃,  ELB의 지연시간(Latency) 등이 대표적인 기본 지표입니다.

일반적인 시스템 모니터링은 기본 지표로 충분합니다만 메모리나 각 마운트된 디스크에 대한 사용률을 확인하려고 할 때는 맞춤형 지표(Custom Metric)를 생성해야 합니다.

맞춤형 지표 만들기
맞춤형 지표란 모니터링하고자 하는 통계치를 여러분이 선정해서 CloudWatch로 보내 관리하는 지표를 말합니다. 맞춤형 지표를 CloudWatch로 보내는 것은 매우 간단합니다. CLI를 사용해서 여러분이 정의한 통계치를 보낼 수 있습니다.

$ aws cloudwatch put-metric-data --metric-name PageViewCount --namespace "MyService" --value 2 --timestamp 2016-01-15T12:00:00.000Z

put-metric-data 명령을 사용해서 원하는 값을 원하는 지표 이름으로 지정해서 보낼 수 있습니다. 위 명령은 “MyService”라는 새로운 서비스명(네임스페이스)으로 지표 이름은 “PageViewCount”로 2의 값을 보내는 명령입니다.

물론 이렇게 명령을 수행하기 위해서는 EC2인스턴스에 CloudWatch에 대한 접근 권한이 있는 역할(Role)이 할당되었거나 aws configure 명령을 사용해서 접근키(access key)와 비밀키(secret key)를 설정해 주어야 합니다.

맞춤형 지표를 퍼블리싱하는 것은 다음 문서에 매우 상세히 설명되어 있습니다.
http://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/DeveloperGuide/publishingMetrics.html

맞춤형 메트릭을 등록하면 CloudWatch 콘솔의 좌측 메뉴 화면 하단에 드롭다운 박스가 생성되면서 본인이 등록한 서비스 명을 확인해 볼 수 있습니다.

Amazon CloudWatch의 차원(dimensions)
CloudWatch에는 차원(dimensions)이라는 개념이 있으며, 이는 데이터를 구분하기 위한 기준을 말합니다. 예를 들어, 아래와 같이 데이터를 보냈다고 가정합시다.

$ aws cloudwatch put-metric-data --metric-name "FileSystem Utilization" --namespace "OurService" --value 16 --unit Percent --dimensions FileSystem="dev/xvda1" --timestamp 2016-01-12T12:00:00.000Z

이렇게 보낸 경우에는 CloudWatch 콘솔에서는 아래와 같은 FileSystem에 대한 차원 정보가 화면이 나오게 됩니다.

만약 여기에 차원을 다음과 같이 해서 추가해 봅니다.

--dimensions FileSystem="dev/xvda1",HostId="ami-249b554a",MountPath="/"

이제 기존 차원에 더해 새로운 차원이 등록 됩니다. 맞춤형 지표에 대해 데이터를 보는 새로운 뷰가 추가된 것을 확인할 수 있습니다.

메모리와 디스크에 대한 지표 등록

이제 리눅스 계열의 OS를 대상으로 메모리와 디스크에 대한 지표를 새로 작성해 보도록 하겠습니다. AWS 문서 중에 이를 수행하기 위한 Perl 스크립트 사용법이 소개되어 있는데 다음 링크에서 볼 수 있습니다.

http://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/DeveloperGuide/mon-scripts.html

위의 Perl 스트립트를 이용해서 메모리와 디스크에 대한 맞춤 지표를 등록할 수 있습니다. 그런데 이 스크립트는 오직 예제로 기술 지원은 제공하지 않습니다. 많은 시스템에서 대부분 제대로 동작하지만,  혹시라도 동작을 하지 않는다면 Perl 스트립트를 수정하면서 적용하는 것은 쉬운 일이 아닙니다.

이를 해결할 간단한 방법 중의 하나가 쉘 스크립트를 이용해서 커스텀 지표를 등록하는 방법입니다. 이 글을 위한 블로그를 위한 커스텀 지표 등록 쉘 스크립트는 아래에서 다운로드 받으실 수 있습니다.

http://awsblogskr.s3-ap-northeast-2.amazonaws.com/articles/2016-01-cloudwatch-seonyong/custom_metric2.sh

이제 이 스크립트에 대해 처음 부터 살펴보겠습니다. 먼저 타임스탬프 값을 얻어오기 위해서 다음과 같은 쉘 스크립트 함수를 정의합니다.

get_time_stamp() {
	time_stamp=$(date -u +%Y-%m-%dT%R:%S.000Z)
	echo "$time_stamp"
}

타입스탬프는 UTF를 기준으로 하기 때문에 –u 옵션을 사용해서 생성합니다. 이 타임스탬프 값은 커스텀 지표를 보낼 때의 타임스탬프 값으로 사용합니다.

다음은 인스턴스의 아이디를 가져오는 함수이다.

get_instance_id() {
	instance_id=$(curl http://169.254.169.254/latest/meta-data/ami-id)
	echo $instance_id
}

여기서 특이한 점은 curl 명령을 사용해서 아이디를 얻어옵니다. 169.254.169.254 주소는 Amazon EC2 인스턴스 내에서 해당 인스턴스의 메타 정보를 가져오는 주소값입니다.

메타정보나 유저정보를 가져올 수 있는 내용에 대해서는 다음 문서에 잘 설명되어 있다.
http://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-retrieval

리눅스 계열의 서버에서 메모리 정보를 가져오는 방법은 여러가지가 있습니다. top, free, vmstat 등 다양하지만 여기서는 /proc/meminfo 파일 정보를 읽어와서 awk로 가공하는 방법을 사용합니다.

free_mem_ratio=$(awk '/MemTotal:/{total=$2} \
       /MemFree:/{free=$2} \
       END{ \
        print (free*100/total); \
       }' /proc/meminfo 

위 코드는 파일을 읽어와서 MemTotal, MemFree정보를 이용해서 자유 메모리의 비율을 계산하는 부분입니다.

디스크의 경우에는 df –h 명령을 이용합니다. 명령의 출력은 시스템 마다 다양한데, 보려고 하는 값들을 탭으로 구분된 문자열로 생성합니다.

declare -a fs_list=$(df -h | awk '$1 ~ /^ *\/dev\//{print $1, "\t", $2, "\t", $3, "\t", $4, "\t", $5, "\t", $6}')

기준은 /dev/로 시작하는 문자열만을 뽑아서, 원하는 지표를 탭 공백이 있는 하나의 문자열로 만듭니다. 물론 /dev/로 시작하는 볼륨이 여럿 있을 수 있으므로 fs_list는 배열로 정의합니다.

이후에 한 문자열에서 원하는 탭 구분 정보를 루프를 돌면서 추출합니다.  이때 G, %같은 문자는 sed를 이용해서 제거합니다.

fs=$(echo $f_info       | sed 's/[G%]//g' | awk '{ print $1}' )

이렇게 만들어진 정보(여기서는 파일시스템, 전체 크기, 사용 중 크기, 사용 가능 크기,  마운트 포인트)를 변수에 담아 CLI를 통해 CloudWatch로 전달합니다.

$ aws cloudwatch put-metric-data --metric-name "Filesystem Utilization" --namespace "OurService" --value $fs_util  --unit Percent --dimensions FileSystem=$fs,HostId=$instance_id,MountPath=$fs_mount --timestamp $time_stamp

시스템에 따라 변경 필요가 있는 부분은 아래 두 부분입니다.

declare -a fs_list=$(df -h | awk '$1 ~ /^ *\/dev\//{print $1, "\t", $2, "\t", $3, "\t", $4, "\t", $5, "\t", $6}')
sed 's/[G%]//g'

출력되는 정보의 위치나 제거해야 할 문자 등이 시스템마다 조금씩 다를 수 있는데, 이는 약간의 주의만 기울이면 쉽게 바꿀 수 있습니다.

이제 쉘 스크립트를 crontab에 등록하면 쉽게 자동화 할 수 있습니다. 다음은 본 예제를 crontab으로 설정 한 것이다. 1분에 한번씩 커스텀 지표를 등록합니다.

$ crontab –e
*/1 * * * * /etc/cronjob/custom_metric2.sh

마지막으로 맞춤형 지표를 등록하는 CLI 명령이나, EC2에 대한 조작을 하는 CLI는 모두 계정별로 일정 정도 성능 제한이 설정되어 있습니다. 따라서 특정 시점에 한꺼번에 요청을 하면 명령이 수행이 안될 가능성이 있습니다. 각 요청은 가능한 동시가 아니라 분산되어 수행되도록 하는 것이 바람직합니다.

이와 관련한 참고 문서는 다음과 같습니다.

http://docs.aws.amazon.com/ko_kr/AWSEC2/latest/APIReference/query-api-troubleshooting.html#api-request-rate

맞춤형 지표는 서비스 모니터링을 강화시키는 효율적인 도구입니다. 가능한 CLI와 연계해서 메트릭을 자동화하는 것이 바람직합니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박선용 솔루션즈 아키텍트께서 작성해주셨습니다.