はじめてのCloudWatch（AWS） 〜カスタムメトリクスを作って無料枠でいろいろ監視する〜


EC2のサーバ監視にCloudWatchを初めて使ってみました。

カスタムメトリクスを作って、CPU使用率、HttpStatus、Memory使用率、LoadAverageの監視を行うようにしたので、手順をまとめておきます。

CloudWatchは無料枠で10メトリクス、10アラームまで設定できるとのことなので嬉しいですね。

以下、[公式サイト](http://aws.amazon.com/jp/cloudwatch/)より引用

>無料利用枠* 
>
>Amazon CloudWatch は無料で始めることができます。アプリケーションの多くは、これらの無料利用枠内で利用できるはずです。
>Amazon EBS ボリューム、Elastic Load Balancers、Amazon RDS DB インスタンスのすべてのメトリックス同様、Amazon EC2 インスタンスの基本モニタリングのメトリックス（5分間隔）は無料でご利用いただけます。
>新規および既存のお客様は、10メトリックス（Amazon EC2 インスタンスまたはカスタムメトリックスの詳細モニタリングに適用）、10アラーム、および100万の API リクエストを追加料金なしでご利用いただけます。

## 1. 標準メトリクスの設定

CloudWatchのデフォルトで用意されている監視項目には以下のようなものがあります。

* CPU Utilization(CPU使用率)
* Disk Reads(ディスク読み込み状況)
* Disk Writes(ディスク書き込み状況)
* Network In,Out(ネットワーク状況)
* Status Check Failed(インスタンスのステータスチェック失敗)

ここでは、CPU使用率のアラート設定をしてみます。

[AWSマネージメントコンソール](https://console.aws.amazon.com/console/home)からEC2メニューにアクセスし、「Instances」からアラート設定したいインスタンスを選択します。

下部にタブメニューが表示されるので「Monitoring」を選択。

![cloudwatch1.png](https://qiita-image-store.s3.amazonaws.com/0/20250/421fc40b-e396-4dfa-5773-c4837b7d5490.png "cloudwatch1.png")

「Create Alarm」をクリックして、アラートを作成します。

今回は以下のようにして、CPU使用率の最大値が80%を超えたら通知するように設定しました。

```
Send a notification to（通知名） : CPUUtilization
With these recipients （通知先メールアドレス）: your_email@example.com
Whenever（条件）：Maximum of CPU Utilization
Is :  >= 80 Percent
For at least :  1 consecutive period(s) of 5 minutes
```

![cloudwatch2.png](https://qiita-image-store.s3.amazonaws.com/0/20250/15605a1c-464c-d8e3-e7c9-496199a708cf.png "cloudwatch2.png")

アラート設定が完了すると「AWS Notification - Subscription Confirmation」というメールが指定したアドレスに届くので、メールのリンクをクリックして通知を有効化しておきます。

## 2. カスタムメトリクスの作成

標準メトリクスでは、Memory使用率、LoadAverage等の情報は監視することができません。

このような場合は、カスタムメトリクスを作成してインスタンスから必要データを取得するようにします。

監視データの送信には aws-apitools-mon というツールを使いますが、Amazon Linuxの場合は、デフォルトで組み込まれています。

以下、[公式ドキュメント](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AmazonLinuxAMIBasics.html)より引用

>Amazon Linux AMI またはリポジトリには、AWS の統合および使用のための、次のよく使用されるコマンドラインツールが組み込まれています。
>aws-amitools-ec2
>aws-apitools-as
>aws-apitools-cfn
>aws-apitools-common
>aws-apitools-ec2
>aws-apitools-elb
>aws-apitools-iam
>aws-apitools-mon
>aws-apitools-rds
>aws-cfn-bootstrap
>aws-scripts-ses
>aws-apitools-mon

 mon-put-data というコマンドを実行して、コマンドが見つからないという表示が出た場合は、

```
yum install aws-apitools-mon
```

でインストールを行ってください。

### 2-1. 監視用スクリプト作成の事前準備

以下はec2-userでログインしている状態で実行します。

監視用スクリプトを置くディレクトリを作成し、credentialファイルを設置します。

```
mkdir ~/cloudwatch
sudo cp /opt/aws/credential-file-path.template ~/cloudwatch/credential
sudo chown ec2-user. ~/cloudwatch/credential
chmod 600 cloudwatch/credential
```

次に、AWSマネージメントコンソールから[IAM](https://console.aws.amazon.com/iam/home)メニューにアクセスし、cloudwatch用のユーザを作成します。

ユーザ作成時に表示される Access Key ID と Secret Access Key をメモしておきます。

Permissions は 「Policy Generator」 を選択し、CloudWatchの「PutMetricData」を許可するようにします。（下図参照）

![cloudwatch3.png](https://qiita-image-store.s3.amazonaws.com/0/20250/e2770a28-a8b3-5887-0386-48e45f951e3a.png "cloudwatch3.png")

![cloudwatch4.png](https://qiita-image-store.s3.amazonaws.com/0/20250/5da7147e-acf3-0150-13a0-2425b74bd02c.png "cloudwatch4.png")

ユーザ作成が完了したら、credential にAccess Key ID と Secret Access Key を記述します。

```~/cloudwatch/credential
AWSAccessKeyId=<Write your AWS access ID>
AWSSecretKey=<Write your AWS secret key>
```

### 2-2. 監視用シェルスクリプト作成

事前準備ができたので、監視用のシェルスクリプトを作成してHttpStatus、Memory使用率、LoadAverageの監視を行うようにします。

各監視項目の取得方法に関しては参考サイトのものを流用させていただきました。

まずは、引数に与えられたURLのHttpStatusを表示するシェルスクリプトを作成します。

```~/cloudwatch/http_status_check.sh
#!/bin/sh
curl -s $1 -o /dev/null -w "%{http_code}"
```
次に、監視データをCloudWatchに送信するシェルスクリプトを作成します。

```~/cloudwatch/custom_metrics.sh
#!/bin/bash

export JAVA_HOME=/usr/lib/jvm/jre
export AWS_CLOUDWATCH_HOME=/opt/aws/apitools/mon
export EC2_REGION=ap-northeast-1
export AWS_CREDENTIAL_FILE=/home/ec2-user/cloudwatch/credential
instanceid=i-**** # EC-2メニューの「Instances」から該当サーバのInstanceIDを取得して記述

# http status check
status=`/home/ec2-user/cloudwatch/http_status_check.sh http://example.com` # 監視したいurlを記述
if [ $status -eq 200 ]; then
Fail=0
else
Fail=1
fi
/opt/aws/bin/mon-put-data --metric-name "Http Status fail" --namespace "Custom Metrix" --dimensions "InstanceId=$instanceid" --value "$Fail" --unit "Count"

# memory check
memtotal=`free -m | grep 'Mem' | tr -s ' ' | cut -d ' ' -f 2`
memfree=`free -m | grep 'buffers/cache' | tr -s ' ' | cut -d ' ' -f 4`
let "memused=100-memfree*100/memtotal"
/opt/aws/bin/mon-put-data --metric-name "FreeMemoryMBytes" --namespace "Custom Metrix" --dimensions "InstanceId=$instanceid" --value "$memfree" --unit "Megabytes"
/opt/aws/bin/mon-put-data --metric-name "UsedMemoryPercent" --namespace "Custom Metrix" --dimensions "InstanceId=$instanceid" --value "$memused" --unit "Percent"

# loadaverage check
loadave1=`uptime | tr -s ' ' | cut -d ' ' -f 11 | cut -d ',' -f 1`
/opt/aws/bin/mon-put-data --metric-name "LoadAverage" --namespace "Custom Metrix" --dimensions "InstanceId=$instanceid" --value "$loadave1" --unit "Count"
```

各シェルスクリプトにcronからの実行権限を付与します。

```
chmod 755 ~/cloudwatch/http_status_check.sh
chmod 755 ~/cloudwatch/custom_metrics.sh
```

5分おきに実行するようにcron設定をします。

```
crontab -e

*/5 * * * * /home/ec2-user/cloudwatch/custom_metrics.sh
```

## 2-3. アラート設定
cronが実行されると、AWSマネージメントコンソールの[CloudWatch](https://console.aws.amazon.com/cloudwatch/home)メニューの「All metrics」内に「Custom Metrix:InstanceId」項目が追加され、シェルスクリプトに設定した値がモニタされるようになります。
（モニタの反映までに多少時間がかかるようです。）

アラート設定したい項目をクリックして、「CreateAlerm」を選択します。

HttpStatusチェックのアラートには5分間で1回以上ステータス200以外が返って来たらアラートが飛ぶように設定しました。

アラート作成画面1（下図参照）では、アラート名と説明、アラート条件を記述します。

![cloudwatch5.png](https://qiita-image-store.s3.amazonaws.com/0/20250/8af52c70-b2d7-7b25-a365-a71c87ab010d.png "cloudwatch5.png")

アラート作成画面2（下図参照）では、アラート時に何をするかを設定できます。

アラート時に特定のメールアドレスに通知を行いたい場合は以下のようにします。
（複数メールアドレスに通知する場合は「,」で区切ります）

```
When Alarm state is : ALARM
Take action : Send Notification
Action details : Topic: 適当な通知名 Email(s): your_email@example.com
```

![cloudwatch6.png](https://qiita-image-store.s3.amazonaws.com/0/20250/6879561b-5370-0a6d-ff2c-122e81e7dd86.png "cloudwatch6.png")

その他の監視項目も同様にアラート設定を行い、以下のような条件でアラート設定を行いました。

```
CPUUtilization >= 80 for 5 minutes
Http Status fail >= 1 for 5 minutes
LoadAverage >= 2 for 5 minutes
UsedMemoryPercent >= 80 for 5 minutes
```

Alert設定した項目はCloudWatchメニューの「Dashboard」に一覧表示されるようになります。

各アラートの条件に関しては適切な設定ができているか不安なところはありますが、これでCloudWatchのアラート設定ができました。

# 編集後記
記事を書きながら色々調べている時に見つけたのですが、[公式の監視スクリプト](http://aws.amazon.com/code/8720044071969977)が公開されているようです。
最初からこっちを使えばよかったですね。。。
次CloudWatchを設定する際はこちらも試してみることにします。

# 参考サイト

* [Amazon CloudWatch](http://aws.amazon.com/jp/cloudwatch/)
* [[AWS]CloudWatchを使ってEC2を監視する方法](http://thinking.ne.jp/2013/01/aws-cloudwatch-ec2/)
* [CloudWatch 標準メトリクス(監視項目) 一覧](http://qiita.com/gohatk@github/items/d1cfcbd1a3c1f7e6b4d3)
* [Amazon Cloud Watch で EC2 インスタンスのプロセス監視を行う](http://d.hatena.ne.jp/hiratake55/20130127/1359301757)
* [Cloud Watchのカスタムメトリクスで特定のurlのhttp status codeを監視する](http://d.hatena.ne.jp/nekonokataomoi/20130701/1372657180)
* [Amazon EC2編～EC2インスタンスを監視するには～](http://recipe.kc-cloud.jp/archives/258)
* [Amazon CloudWatch編～監視スクリプトを使ってみよう！パート②～](http://recipe.kc-cloud.jp/archives/2145)
* [CloudWatchのカスタムメトリクスでFreeMemoryMBytes、UsedMemoryPercent、LoadAverage、Stealを取得](http://dev.classmethod.jp/cloud/cloudwatch-custom-metrics-vmstat-free-uptime/)
* [Awsをちゃんと使ってみた 監視編](http://sssslide.com/www.slideshare.net/rs_wisteria/aws-20006038)
* [【AWS】CloudWatch入門／EC2のステータスチェックを行ってみよう](http://dev.classmethod.jp/etc/cloudwatch-metrics-for-ec2-status-checks/)
* [ステップ 10: CloudWatch アラームを作成する](http://docs.aws.amazon.com/ja_jp/gettingstarted/latest/computebasics-linux/getting-started-create-cloudwatch.html)
* [Amazon Linux AMI の基本](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AmazonLinuxAMIBasics.html)
* [CloudWatch Monitoring ScriptでDiskUsageやMemoryUsage等を取得](http://dev.classmethod.jp/cloud/aws/cloudwatch-monitoring-script-for-linux/)