CloudWatch-Agentを使ってメモリ監視をする

# 背景

ElasticBeanstalk上のEC2に対しメモリ監視を行いたかったので、CloudWatch-Agentを使うことにしました。

# 環境

- ElasticBeanstalk
    - Python 3.6 running on 64bit Amazon Linux

# インストール

AWS公式の[CloudWatch エージェントのインストール](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-on-EC2-Instance.html) によれば

- コマンドライン
- Systems Manager
- CloudFormation

この3つの方法のいずれかでインストールできる。今回はコマンドラインでインストールする方法を選択。

## IAM

EC2に関連付けられたIAMロールに ポリシー `CloudWatchAgentServerPolicy` を追加。

## Agentのインストール

EC2の中にて

```
$ wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
$ sudo rpm -U ./amazon-cloudwatch-agent.rpm
```

## collectdのインストールと設定

メモリ監視にはAgentの他にcollectdも必要なのでインストール。

```
$ sudo yum install collectd
$ sudo yum install collectd-python
$ git clone https://github.com/awslabs/collectd-cloudwatch.git
$ cd collectd-cloudwatch/src
$ vim setup.py # 編集(後述)
$ sudo ./setup.py
```

### collectd-cloudwatchのsetup.py の編集

ハマったところです。

setup.pyはPython2で書かれているが、ElasticBeanstalkのデフォルトのPythonが3.6なので動かない。

そのためsetup.pyの1行目を以下に変更。`sudo python2.7 ./setup.py` として良いです。

```
#!/usr/bin/env python2.7
```

再度実行しようとすると以下のメッセージが出た。インスタンスmetaデータを取りにいけずリージョンなどの情報が取得できない模様。

```
INFO:urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254

AWS region could not be automatically detected. Cause:Cannot access metadata service. Cause: Timeout value connect was (0.3, 0.5), but it must be an int or float.
```

ソースを見ると、タプルを渡せずrequestsが例外を吐いていました。理由は不明(このEBのpython環境の問題かもしれません)

```python:setup.py
_CONNECT_TIMEOUT_IN_SECONDS = 0.3
_RESPONSE_TIMEOUT_IN_SECONDS = 0.5
_REQUEST_TIMEOUT = (_CONNECT_TIMEOUT_IN_SECONDS, _RESPONSE_TIMEOUT_IN_SECONDS)

(略)

 result = session.get(self.metadata_server + request, timeout=self._REQUEST_TIMEOUT)
```

timeout値をベタ書きに変更して対処しました。

```
result = session.get(self.metadata_server + request, timeout=1)
```

あとは設定を選んでいくだけです。ほぼデフォルト値にしました。

## CloudWatchAgentの設定


[ウィザードを使用して CloudWatch エージェント設定ファイルを作成する](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html)

ウィザードを立ち上げてCloudWatchAgentのほうの設定を行います。これもほぼデフォルトです。

`sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard`

StatsDは使わないので2。

```
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:
```

コア毎は不要なので2

```
Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
1. yes
2. no
default choice: [1]:
```

折角ならメモリ以外の項目も見たいのでStandardを選択。

```
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:
```

ログファイルのモニタリングは2。

```
Do you want to monitor any log files?
1. yes
2. no
default choice: [1]:

```

設定内容は `/opt/aws/amazon-cloudwatch-agent/bin/config.json` に出力されるので以下で起動開始。

```
 sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c  file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
```

後はCloudWatchのアラーム設定をすれば完了です(Slack通知させるようにしました)。

# 参考

ありがとうございました。

- [EC2のメモリ監視をCloudWatch Agentで実施してみた | Developers.IO](https://dev.classmethod.jp/articles/monitor-ec2-memory-cw-agent/)
- [CloudWatch で EC2 のメモリ・ディスク使用率を監視する](https://engineers.weddingpark.co.jp/?p=2701)
- [【新機能】カスタムメトリクスとCloudWatchアラームが秒間隔で利用可能になりました！](https://dev.classmethod.jp/articles/high_resolution_custom_metrics_and_alarms_cloudwatch/)
- [CloudWatchまとめ](https://qiita.com/WisteriaWave/items/8e2510264839923c5bbc)