CloudWatchのカスタムメトリクスでDiskUsageを取得

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

今回は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
[/bash]

<p>スクリプトの記述が完了したらファイルを保存して、実行してみます。</p>

$ 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

まとめ

  1. CloudWatchのコマンドラインツールはec2-userで実行すること
  2. 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)

これで自動セットされるので、更に汎用化できるのではないかと思います。