CloudWatchカスタムメトリクス取得用Bashスクリプト雛形

2015.07.29

CloudWatchはAWSが提供するメトリクス保存・監視サービスです。EC2のCPU使用率やNetwork I/Oなどの基本的なメトリクスを、何も追加で作業することなく無料で監視することができます。

一方で、デフォルトでは監視されない項目もカスタムメトリクスという方法を利用すれば、任意の値をCloudWatchに登録することが可能です。カスタムメトリクス登録のためにはCloudWatchのAPI経由で値の登録をする必要が有るため、AWS SDKやAWS CLIが利用されることが多いです。

カスタムメトリクスに簡単に値を追加できるように、登録するときのbashスクリプトを雛形として作ってみました。

スクリプト

例として、ディスク使用率をCloudWatchカスタムメトリクスとして送信するスクリプトを作成しました。

#!/bin/bash

log() {
  echo $1 | logger
}

# CloudWatchに登録する値
usage=$(df  | sed -e 1d -e 's/%//' | awk '{print $5}' | sort -nr | head -n 1)

# DimensionにインスタンスIDを指定する場合
# Dimensionには任意のKey-Valueを指定することが可能
instanceId=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

# インスタンス稼働リージョンの取得
region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')

cw_opts="--namespace Example/EC2"
cw_opts=${cw_opts}" --metric-name DiskUsage"
cw_opts=${cw_opts}" --dimensions InstanceId=${instanceId}"
cw_opts=${cw_opts}" --unit Percent"
cw_opts=${cw_opts}" --region ${region}"
cw_opts=${cw_opts}" --value ${usage}"

# cron等でAPIリクエストが集中するのを防ぐためある程度wait
sleep $(($RANDOM % 15))

counter=0
MAX_RETRY=3

while :; do
  aws cloudwatch put-metric-data ${cw_opts}
  if [ $? -ne 0 ]; then
    if [ "${counter}" -ge "${MAX_RETRY}" ]; then
      log "failed to put metrics."
      exit 1
    fi
  else
    break
  fi

  counter=$((counter + 1))
  sleep 10
done

exit 0

7行目の$usageが、CloudWatchに登録される値になります。このコマンドを任意のコマンドに切り替えることで新しい内容の登録が可能になります。$cw_optsはCloudWatchのAPI実行時の引数になるので、この値は状況によって書き換えてあげましょう(例えば、--unitをPercentからMegabytesにする)。詳細はAPI Documentを参照して下さい。

また、ちょっと重要な点として、APIリクエストの実行前にランダムでsleepをかけています。CloudWatchのスクリプトはcronで定期的に実行されるケースが多いと重いますが、多数のインスタンスで毎分0秒に同時にAPIリクエストが発生すると、APIスロットリングでエラーになる可能性があります。そのため、APIリクエストのタイミングをある程度分散させておいたほうが安全でしょう。

まとめ

これを利用してガンガンCloudWatchに登録していきましょう。ただし、1カスタムメトリクスあたり$0.50/月の料金が発生するので、そこには注意しておきましょう。