CloudWatchのカスタムメトリクスでDiskUsageを取得
今回はCloudWatchのカスタムメトリクスでFreeMemoryMBytes、UsedMemoryPercent、LoadAverage、Stealを取得を参考にDisk使用量を取得するシェルを作ってみました。
このシェルの仕様としてはdfコマンドで認識されているファイルシステム(パーティション)で且つ/dev/を含むパーティションのDisk使用量の内、一番使用量の多いDisk使用量を返すものとなっています。
例えば以下の様なファイルシステムの場合
$ df -k Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 1032142 38672 910900 4% / /dev/ad0s1g 68468192 25964578 37026160 41% /home /dev/ad0s1e 4129310 241610 3557356 6% /usr /dev/ad0s1f 4129310 32244 3766722 1% /var procfs 4 4 0 100% /proc
結果として、41%が返ることになります。
CloudWatchのコマンドラインツール
CloudWatchにメトリクスデータを登録するために、CloudWatchコマンドラインツールを使えるようします。
$ wget http://ec2-downloads.s3.amazonaws.com/CloudWatch-2010-08-01.zip $ unzip CloudWatch-2010-08-01.zip $ cd CloudWatch-1.0.12.1 $ cp -Rp credential-file-path.template credentials $ vi credentials
AWS Management ConsoleのSecurity Credentialsを選択してアクセスキーとシークレットアクセスキーを取得しました。
AWSAccessKeyId=アクセスキーIDで発行されているキー AWSSecretKey=シークレットアクセスキー(表示をクリックして表示されるキー)
shellを作成する
作成したshellは一応パスの通る/home/ec2-user/CloudWatch-1.0.12.1/binの配下に配置することにします。
$ cd /home/ec2-user/CloudWatch-1.0.12.1/bin $ touch check_status.sh $ chmod 755 !$ $ vi !$
shellは以下の通りで作ってみました。
#!/bin/bash export AWS_CLOUDWATCH_HOME=/home/ec2-user/CloudWatch-1.0.12.1 export AWS_CREDENTIAL_FILE=$AWS_CLOUDWATCH_HOME/credentials export AWS_CLOUDWATCH_URL=https://monitoring.amazonaws.com export PATH=$AWS_CLOUDWATCH_HOME/bin:$PATH export JAVA_HOME=/usr/lib/jvm/jre l_num=1 disk_max=0 df_result=/tmp/disk_usage.txt if [ $# -ne 1 ]; then echo "usage : check_status.sh /tmp/filename" exit 1 fi if [ -a $df_result ]; then rm -f $df_result fi df -k > $1 # set ec2 instance id instanceid="i-09228009" exec 3< $1 while read FL 0<&3 do if [ $l_num -eq 1 ] ; then l_num=`expr $l_num + 1` else echo $FL | grep /dev/ | tr -s ' ' | cut -d ' ' -f 5 | sed -e s/%// >> $df_result fi done exec 3<&- while read LINE; do if [ $disk_max -lt $LINE ] ; then disk_max=`expr $LINE` fi done < $df_result mon-put-data --metric-name "DiskUsed" --namespace "System/Linux" --dimensions "InstanceId=$instanceid" --value "$disk_max" --unit "Percent" --region ap-northeast-1
スクリプトの記述が完了したらファイルを保存して、実行してみます。
$ check_status.sh /tmp/disk_describe.txt
スクリプトが正常に終了していたならば/tmp配下に2つのファイルができてるはずです。
$ ls -l /tmp/*.txt -rw-r--r-- 1 ec2-user ec2-user 190 Apr 4 08:35 /tmp/disk_describe.txt -rw-r--r-- 1 ec2-user ec2-user 5 Apr 4 08:35 /tmp/disk_usage.txt
cronにshellを登録する
先ほど作ったshellをcronに登録して指定間隔で実行するように設定します。
※もしec2-userではなく、rootユーザで作業をされている場合は以下の様にしてec2-userで実行するようにします。
# crontab -u ec2-user -e
※rootでcronを実行した場合はCloudWatchのコマンドラインツールのmon-put-dataが動作しませんでした。
※ec2-userの場合は以下でOK
$ crontab -e
とりあえず動作確認するので、1分おきに実行される様に設定してみます。
*/1 * * * * /home/ec2-user/CloudWatch-1.0.12.1/bin/check_status.sh /tmp/disk_describe.txt
$ sudo tail -f /var/log/cron Apr 4 08:35:01 ip-10-148-61-156 CROND[21955]: (ec2-user) CMD (/home/ec2-user/CloudWatch-1.0.12.1/bin/check_status.sh /tmp/disk_describe.txt) Apr 4 08:36:01 ip-10-148-61-156 CROND[21989]: (ec2-user) CMD (/home/ec2-user/CloudWatch-1.0.12.1/bin/check_status.sh /tmp/disk_describe.txt) Apr 4 08:37:01 ip-10-148-61-156 CROND[22022]: (ec2-user) CMD (/home/ec2-user/CloudWatch-1.0.12.1/bin/check_status.sh /tmp/disk_describe.txt) Apr 4 08:38:01 ip-10-148-61-156 CROND[22054]: (ec2-user) CMD (/home/ec2-user/CloudWatch-1.0.12.1/bin/check_status.sh /tmp/disk_describe.txt) Apr 4 08:39:01 ip-10-148-61-156 CROND[22086]: (ec2-user) CMD (/home/ec2-user/CloudWatch-1.0.12.1/bin/check_status.sh /tmp/disk_describe.txt)
Management Consoleで内容を確認する
動作に問題がないようなので、毎日23時に一度実行されるように設定を変更します。
$ crontab -e
crontabの中身
* 23 * * * /home/ec2-user/CloudWatch-1.0.12.1/bin/check_status.sh /tmp/disk_describe.txt
まとめ
- CloudWatchのコマンドラインツールはec2-userで実行すること
- EC2 instanceのavailability zoneは本来ap-northeast-1aにあるがCloudWatchのコマンドラインツールで指定する場合はap-northeast-1と指定しないと動作しない。(ap-northeast-1a,ap-northeast-1bまで指定しないこと)
2012年4月12日 追記
サンプルのshellの中の記述に
# set ec2 instance id instanceid="i-09228009"
と言う記述部分がありますが、インスタンスIDを自動セットする場合は以下の様に変更します。
# set ec2 instance id instanceid=$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)
これで自動セットされるので、更に汎用化できるのではないかと思います。