AWSでCloudWatchエージェントを入れてみた

# はじめに
AWSでCloudWatchエージェントをEC2に入れてメトリクスをとってみました。

# CloudWatchエージェントとは？
公式ドキュメントには以下の内容が記述されています。

```
・オペレーティングシステム全体で Amazon EC2 インスタンスから内部システムレベルのメトリクスを収集します。このメトリクスには、EC2 インスタンスのメトリクスに加えて、ゲスト内メトリクスを含めることができます。収集することができる追加のメトリクスについては、「CloudWatch エージェントにより収集されるメトリクス」を参照してください。

・オンプレミスサーバーからシステムレベルのメトリクスを収集します。これには、ハイブリッド環境のサーバーや AWS によって管理されていないサーバーも含まれる可能性があります。

・カスタムメトリクスは、StatsD および collectd プロトコルを使用して、アプリケーションまたはサービスから取得します。StatsD は、Linux サーバーと、Windows Server を実行するサーバーの両方でサポートされています。collectd は、Linux サーバーでのみサポートされています。

・Linux または Windows Server を実行している Amazon EC2 インスタンスおよびオンプレミスサーバーから､ログを収集します。
```

ざっくり言えば、EC2からたくさんのメトリクスが取れるよって話です。
どうやら、AWS上のサーバだけでなく、オンプレミスのサーバも取得できるみたいですね。
CloudWatchで取れるメトリクスって何があるの？って気になるかもしれませんが、
以下の公式ドキュメントを確認すれば良いと思います。

[【CloudWatchエージェントにより収集されるメトリクス】](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/metrics-collected-by-CloudWatch-agent.html)

# とりあえずやってみた
### EC2インスタンスを用意
まずはEC2インスタンスを用意しましょう。
私の場合は、EC2インスタンスにApacheだけ導入してそれ以外の設定はデフォルトです。
![スクリーンショット 2021-07-22 10.53.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/18143dc8-fc9f-8284-d30f-7831b525eedd.png)

### EC2インスタンスにIAMロールをアタッチする
今回実装する上で必要なIAMロールは、
”サーバがCloudWatchエージェントを実行するためのロール”と
”管理者がParameter Storeに書き込むためのロール”です。

具体的には以下のポリシーを追加してロールを作成します。
(ロール名は任意です)
![スクリーンショット 2021-07-22 11.19.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/d00090cd-b1f6-2098-cd51-b84034988820.png)

EC2インスタンスにIAMロールをアタッチ
![スクリーンショット 2021-07-22 11.27.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/74d51648-6e5b-d531-6992-b5424bbbe8ed.png)
![スクリーンショット 2021-07-22 11.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/df3fb851-8069-da9d-31de-a64e2f82bb0a.png)



### EC2インスタンスにCloudWatchエージェントを導入する
CloudWatchエージェントを導入する方法は、２通りあります。
①Systems Managerを使用してインストール
②Amazon LinuxのOSパッケージからインストール

今回は、②の方法で導入していきます。
注意事項としては、EC2インスタンスに"CloudWatchAgentServerPolicy"のポリシーがアタッチされているか再確認してください。（先ほどのIAMロールをアタッチしていれば問題ありません）

まずは、EC2インスタンスへSSH接続して、パッケージをダウンロードしてその後インストールします。
（今回は東京リージョンを使いますが、それ以外を使う場合は"ap-northeast-1"の部分を変更ください）

```
wget https://s3.ap-northeast-1.amazonaws.com/amazoncloudwatch-agent-ap-northeast-1/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
```

```
sudo rpm -U ./amazon-cloudwatch-agent.rpm
```

### CloudWatchエージェントの設定ファイルを作成する
エージェントを起動する前に設定ファイルを作成します。
以下のコマンドを実行するとウィザードが起動してエージェントの設定ファイルを作成することができます。

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

ウィザードを起動すると次々と質問が出てくるのでお使いの環境や要件に合わせた内容を回答していきましょう。

```
[ec2-user@ip-10-0-1-140 ~]$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
=============================================================
= Welcome to the AWS CloudWatch Agent Configuration Manager =
=============================================================
On which OS are you planning to use the agent?
1. linux
2. windows
3. darwin
default choice: [1]:
```

上記ではどのOSでエージェントを使用するかを聞いていて、デフォルトでは"Linux"が選択されています。
今回はAmazon Linux2を使用しているのでそのまま「Enter」で進めましょう。

```
Are you using EC2 or On-Premises hosts?
1. EC2
2. On-Premises
default choice: [1]:
```

上記では使っているホストはEC2かオンプレミスかを聞いていて、デフォルトでは"EC2"が選択されています。
今回はEC2インスタンスを使用しているのでそのまま「Enter」で進めます。

```
Which user are you planning to run the agent?
1. root
2. cwagent
3. others
default choice: [1]:
```

上記ではエージェントを実行するユーザを聞いていて、デフォルトでは"root"が選択されています。
今回はrootユーザで進めます。

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

上記ではStatsデーモンを使いますかを聞いています。
Statsデーモンはざっくり言えばメトリクスを収集するツールのことです。
追加でカスタムメトリクスを使用する場合は有効にしています。
今回は使用するのでそのまま進めます。

```
Which port do you want StatsD daemon to listen to?
default choice: [8125]
```

上記ではStatsデーモンの待ち受けるポート番号は8125でいいですかという質問です。
特に指定の要件がなければ8125で良いと思うので今回はこのまま進めます。

```
What is the collect interval for StatsD daemon?
1. 10s
2. 30s
3. 60s

```

上記ではStatsデーモンの収集間隔を聞いています。
今回は10秒間隔で進めます。デフォルトは10秒です。

```
What is the aggregation interval for metrics collected by StatsD daemon?
1. Do not aggregate
2. 10s
3. 30s
4. 60s
default choice: [4]:
```

上記ではStatsデーモンが収集したメトリクスを集約する周期を聞いています。
今回はデフォルトのままで進めます。

```
Do you want to monitor metrics from CollectD?
1. yes
2. no
default choice: [1]:
```

Collectデーモンを使ってメトリクスを収集しますかと聞いています。
CollectデーモンとはStatsデーモンと似たようなプロトコルでメトリクスを収集するツールですね。
今回は使用しなくても良いです。

```
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:
```

CPUやメモリを収集したいですかと聞いているので、収集しましょう。

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

コアあたりのCPUを監視するかを聞いているので、有効にしておきましょう。

```
Do you want to add ec2 dimensions (ImageId, InstanceId, InstanceType, AutoScalingGroupName) into all of your metrics if the info is available?
1. yes
2. no
default choice: [1]:
```

メトリクスに利用可能なディメンションを利用するかを聞いているので、利用しておきましょう。

```
Would you like to collect your metrics at high resolution (sub-minute resolution)? This enables sub-minute resolution for all metrics, but you can customize for specific metrics in the output json file.
1. 1s
2. 10s
3. 30s
4. 60s
default choice: [4]:
```

高解像度でのメトリクスの収集間隔を聞いています。
特に指定した要件がなければデフォルト(60秒）でいいと思います。

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

メトリクスセットを選択してくださいという意味です。
今回はサービス監視を実装したいだけなので最低限の必要な"Basic"でいきましょう。

```
Current config as follows:
{
	"agent": {
		"metrics_collection_interval": 60,
		"run_as_user": "root"
	},
	"metrics": {
		"append_dimensions": {
			"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
			"ImageId": "${aws:ImageId}",
			"InstanceId": "${aws:InstanceId}",
			"InstanceType": "${aws:InstanceType}"
		},
		"metrics_collected": {
			"disk": {
				"measurement": [
					"used_percent"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 10,
				"service_address": ":8125"
			}
		}
	}
}
Are you satisfied with the above config? Note: it can be manually customized after the wizard completes to add additional items.
1. yes
2. no
default choice: [1]:
```

先ほどの質問で答えた内容をもとに設定ファイルが作成されました。
この内容で問題がないか確認しているので、問題がなければ「yes」と進めましょう。
内容に不満であれば「no」と選択して、質問に戻ります。


```
Do you have any existing CloudWatch Log Agent (http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html) configuration file to import for migration?
1. yes
2. no
default choice: [2]:
```

既にCloudWatchエージェントが存在するかを聞いています。
今回は新規なので、「no」と選択しましょう。

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

ログファイルの監視を行うかを聞いています。
そのままデフォルトで進めましょう。

```
Log file path:
```

どのログを監視するかを聞いているのでファイルを指定してあげましょう。
今回はシステムログ「/var/log/messages」にしています。

```
Log group name:
default choice: [messages]
```

ロググループ名を聞いています。
デフォルトで進めましょう。

```
Log stream name:
default choice: [{instance_id}]
```

ログストリーム名を聞いているので、このままデフォルトで大丈夫です。

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

監視する追加のログファイルを指定しますか？と聞いています。
今回は追加でログファイル監視はしないので「no」で進めます。

```
Saved config file to /opt/aws/amazon-cloudwatch-agent/bin/config.json successfully.
Current config as follows:
{
	"agent": {
		"metrics_collection_interval": 60,
		"run_as_user": "root"
	},
	"logs": {
		"logs_collected": {
			"files": {
				"collect_list": [
					{
						"file_path": "/var/log/messages",
						"log_group_name": "messages",
						"log_stream_name": "{instance_id}"
					}
				]
			}
		}
	},
	"metrics": {
		"append_dimensions": {
			"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
			"ImageId": "${aws:ImageId}",
			"InstanceId": "${aws:InstanceId}",
			"InstanceType": "${aws:InstanceType}"
		},
		"metrics_collected": {
			"disk": {
				"measurement": [
					"used_percent"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 10,
				"service_address": ":8125"
			}
		}
	}
}
Please check the above content of the config.
The config file is also located at /opt/aws/amazon-cloudwatch-agent/bin/config.json.
Edit it manually if needed.
Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]:
```

設定ファイルはこんな感じですと言ってます。
SSMのパラメータストアに保存してもいいですかと聞いているので「yes」としましょう。

```
What parameter store name do you want to use to store your config? (Use 'AmazonCloudWatch-' prefix if you use our managed AWS policy)
default choice: [AmazonCloudWatch-linux]
```

パラメータストアに保存する名前を入れてあげましょう。
今回はデフォルトで進めます。

```
Trying to fetch the default region based on ec2 metadata...
Which region do you want to store the config in the parameter store?
default choice: [ap-northeast-1]
```

パラメータストアのリージョンを指定してください。
今回は東京リージョン(ap-northeast-1)です。

```
Which AWS credential should be used to send json config to parameter store?
1. ASIA2WFBCGF2A2YFDQ77(From SDK)
2. Other
default choice: [1]:
```

設定ファイルをパラメータストアに送信するためのクレデンシャルをどうしますかと聞かれていますので
デフォルトのままで進めてください。

```
Successfully put config to parameter store AmazonCloudWatch-linux.
Program exits now.
```

これで設定ファイルが作成できました！
設定ファイルは「/opt/aws/amazon-cloudwatch-agent/bin/config.json」で保存されているので確認しましょう。

### SSMからエージェントを起動する
インスタンスでのエージェント設定が完了したら、SSMのRunCommandでエージェントを起動します。
![スクリーンショット 2021-07-23 10.20.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/e0ee15c3-efaf-29c6-5ea8-8c9761350783.png)

コマンドドキュメントで「AmazonCloudWatch-ManageAgent」を選択して、下にページが展開されたので以下の項目へ値を入力していきます。
（記載のない項目はデフォルトで構いません）
・Optional Configuration Location
パラメータストアに保存されているファイル名を入力ください
今回であれば、「AmazonCloudWatch-linux」ですね。

ターゲットは、「インスタンスを手動で選択する」を選択し、以下のように対象のEC2インスタンスを選択していきます。
![スクリーンショット 2021-07-23 10.29.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/a322bc2a-ce10-26f4-db29-7e5900a6afdb.png)

タイムアウトは、最低値の30秒にしておきましょう。

実行するとコマンドの結果が返ってくるので「ターゲットと出力」のインスタンスIDをクリックすると実行した内容と結果が見えます。
確認していきましょう。
![スクリーンショット 2021-07-23 10.37.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/69f95167-f624-3f1a-1c53-310c99e6bab4.png)

OutputとErrorの２種類の出力があり、それぞれ以下の記載がありました。
「Output」

```
****** processing amazon-cloudwatch-agent ******
/opt/aws/amazon-cloudwatch-agent/bin/config-downloader --output-dir /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d --download-source ssm:AmazonCloudWatch-linux --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml --multi-config default
Region: ap-northeast-1
credsConfig: map[]
Successfully fetched the config and saved in /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_AmazonCloudWatch-linux.tmp
Start configuration validation...
/opt/aws/amazon-cloudwatch-agent/bin/config-translator --input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --input-dir /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d --output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml --multi-config default
Valid Json input schema.
I! Detecting run_as_user...
No csm configuration found.
Configuration validation first phase succeeded
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -schematest -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml
Configuration validation second phase succeeded
Configuration validation succeeded
amazon-cloudwatch-agent has already been stopped

```

基本的に「succeed」の記載があれば正常に実行されたものとみなしてOKです。

「Error」

```
2021/07/23 01:37:12 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_AmazonCloudWatch-linux.tmp ...
Created symlink from /etc/systemd/system/multi-user.target.wants/amazon-cloudwatch-agent.service to /etc/systemd/system/amazon-cloudwatch-agent.service.
Redirecting to /bin/systemctl restart amazon-cloudwatch-agent.service

```

一見エラーがあるぞ！と思われるかもしれませんが、この記述はウィザードで作った設定ファイルを読み込んで
systemctlターゲットのシンボリックリンクを作成しましたよっていう出力です。
エラーではありませんのでこのまま進めていきましょう。

### CloudWatchの内容を確認する。
まずログの内容を確認していきます。
CloudWatchの画面に移動して、「ロググループ」を選択すると「messages」のが記載されていますね。
![スクリーンショット 2021-07-23 10.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/09a73810-44bd-c5e7-cab4-ebf7d3dcc710.png)

中を開いてみましょう。
![スクリーンショット 2021-07-23 10.50.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/fa606e55-1984-0d30-8ef7-e8c1a2710bef.png)

ログストリーム名をクリックすると、EC2インスタンスのログが確認できました。
![スクリーンショット 2021-07-23 10.51.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/b28da3b5-c9d7-f0a1-aad3-e35bd919db68.png)

# 参考
[【Amazon EC2 インスタンスの CloudWatch エージェントで使用する IAM ロールを作成する】](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html#create-iam-roles-for-cloudwatch-agent-roles)
[【コマンドラインを使用して CloudWatch エージェントをダウンロードおよび設定する】](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/download-cloudwatch-agent-commandline.html)
[【ウィザードを使用して CloudWatch エージェント設定ファイルを作成する】](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html)
[【collectd を使用してカスタムメトリクスを取得する】](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-custom-metrics-collectd.html)
[【StatsD を使用してカスタムメトリクスを取得する】](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-custom-metrics-statsd.html)