Cloudwatchでインスタンスを監視をする

# 概要
CloudwatchAgentを用いたEC2インスタンスの監視をやります。

## エンドポイントを作る
プライベートサブネットからCloudWatch Agentを利用する場合は下記のエンドポイントを作成する必要があります。
VPCからエンドポイントを作成してください。

```
com.amazonaws.ap-northeast-1.monitoring
com.amazonaws.ap-northeast-1.ec2
com.amazonaws.ap-northeast-1.logs
```

## IAMポリシーを作る
下記の権限を持つポリシーを作成し、CloudwatchAgentを入れるEC2にアタッチします。
- CloudWatchAgentServerPolicy

エラーに苦しんだら下記を当ててください。正直権限的にやりすぎなので切り分けなどの目的で行うことを推奨します。
- AmazonEC2ReadOnlyAccess
- CloudWatchFullAccess
- AmazonSSMFullAccess

## セキュリティグループに穴をあける
Port8125に対してAWSからのアクセスがありますので開けましょう。
このポート番号はCloudWatchAgentの設定ファイルで変更することができます。

## コンソールログインする
対象EC2にログインします。
EC2 Instance Connectでも問題ないです。私はローカルからsshでログインしてます。
また、今回対象となるインスタンスはamazon-linuxなどのamazonから標準的に提供されているamiを使用していることを前提とします。環境が特殊なオンプレサーバー等も基本は変わらないですけどね。サーバーからインターネットに出れることが最低限の条件です。

## cloudwatch-agentの導入
EC2にcloudwatch-agentを導入する必要があります。
下記を打って返値が無ければそのインスタンスにはcloudwatch-agentが入っていません。
```
[ec2-user@ip-10-40-0-10 ~]$ sudo yum list installed | grep cloudwatch
[ec2-user@ip-10-40-0-10 ~]$

```
ではインストールします。

```
[ec2-user@ip-10-40-0-10 ~]$ sudo yum install amazon-cloudwatch-agent
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                                         | 3.7 kB  00:00:00
Resolving Dependencies
--> Running transaction check
---> Package amazon-cloudwatch-agent.x86_64 0:1.247350.0-1.amzn2 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==========================================================================================================================================================================================
 Package                                              Arch                                Version                                           Repository                               Size
==========================================================================================================================================================================================
Installing:
 amazon-cloudwatch-agent                              x86_64                              1.247350.0-1.amzn2                                amzn2-core                               45 M

Transaction Summary
==========================================================================================================================================================================================
Install  1 Package

Total download size: 45 M
Installed size: 203 M
Is this ok [y/d/N]: y

~snip~

Complete!
[ec2-user@ip-10-40-0-10 ~]$
```

```
[ec2-user@ip-10-40-0-10 ~]$ sudo yum list installed | grep cloudwatch
amazon-cloudwatch-agent.x86_64        1.247350.0-1.amzn2             @amzn2-core
```

簡単ですね。

## cloudwatch-agentの設定ファイル(JSON)を作成する
標準で提供されているウィザードを使って実施します。

ウィザードはこいつです(/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard)
```
[ec2-user@ip-10-40-0-10 etc]$ ls /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
```

これを実行する前に設定ファイルを置くpathに移動しましょう。
```
[ec2-user@ip-10-40-0-10 etc]$ cd /opt/aws/amazon-cloudwatch-agent/etc
```
ウィザードを起動
```
[ec2-user@ip-10-40-0-10 etc]$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
```

あとは対話に従って選択していくだけです。
注意点として、途中でどのメトリクス構成が必要か聞かれます。

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

これについては下記の公式ドキュメントの[CloudWatch エージェントの事前定義されたメトリクスセット]を確認し、なんのメトリクスを監視したいのかを考慮して選択してください

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html

diskやメモリの使用量を％で見たいだけならBasicで大丈夫です。

## Cloudwatch-agentを起動する
設定ファイルは作りましたが、agentをまだ動かしていません。
```
[ec2-user@ip-10-40-0-10 etc]$ sudo systemctl status amazon-cloudwatch-agent
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
   Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
[ec2-user@ip-10-40-0-10 etc]$
```
動かさなくてはなりませんが、この時点だとせっかく作った設定ファイルが適切な位置にありません。
ウィザードで作成したファイルは下記のpathにあります。
```
[ec2-user@ip-10-40-0-10 etc]$ ls /opt/aws/amazon-cloudwatch-agent/bin/config.json
/opt/aws/amazon-cloudwatch-agent/bin/config.json
```
このファイルをウィザード実行前に移動したカレントディレクトリ(/opt/aws/amazon-cloudwatch-agent/etc)に移しましょう。ついでに名前もそれっぽく変えておきます(amazon-cloudwatch-agent.json)
```
[ec2-user@ip-10-40-0-10 etc]$ sudo cp ../bin/config.json ./amazon-cloudwatch-agent.json
[ec2-user@ip-10-40-0-10 etc]$ ls
amazon-cloudwatch-agent.d  amazon-cloudwatch-agent.json  common-config.toml
[ec2-user@ip-10-40-0-10 etc]$
```
この後、実はいろいろハマったんですが(後述)基本的に起動すれば動きます。
```
[ec2-user@ip-10-40-0-10 etc]$ sudo systemctl restart amazon-cloudwatch-agent
[ec2-user@ip-10-40-0-10 etc]$ sudo systemctl status amazon-cloudwatch-agent
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
   Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2022-07-11 11:58:50 UTC; 3s ago
 Main PID: 5182 (amazon-cloudwat)
   CGroup: /system.slice/amazon-cloudwatch-agent.service
           └─5182 /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml -envconfig /opt/aws/amazon-cloudwatch-agent/etc/env-config.json -pidfile /o...

Jul 11 11:58:50 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: Started Amazon CloudWatch Agent.
Jul 11 11:58:50 ip-10-40-0-10.ap-northeast-1.compute.internal start-amazon-cloudwatch-agent[5182]: Valid Json input schema.
Jul 11 11:58:50 ip-10-40-0-10.ap-northeast-1.compute.internal start-amazon-cloudwatch-agent[5182]: I! Detecting run_as_user...
[ec2-user@ip-10-40-0-10 etc]$
```

次に作成した設定ファイル(amazon-cloudwatch-agent.json)を適用します。
```
[ec2-user@ip-10-40-0-10 etc]$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -s -m ec2 -c file:amazon-cloudwatch-agent.json
****** 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 file:amazon-cloudwatch-agent.json --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml --multi-config default
Successfully fetched the config and saved in /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_amazon-cloudwatch-agent.json.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
2022/07/11 12:42:39 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_amazon-cloudwatch-agent.json.tmp ...
Valid Json input schema.
I! Detecting run_as_user...
No csm configuration found.
No log 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
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
```
`file:[path]`なので、カレントディレクトリに設定ファイルがないならしっかり指定する事。

この後、場合によってはcloudwatchagentを再起動してください

Cloudwatchを見た時に[CWAgent]というカスタム名前空間が追加されていればok

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1206561/8d6bab82-fa49-0819-ad3e-2bff81d28a0b.png)


## ハマったポイント
agentが起動できず四苦八苦しました。
`systemctl status amazon-cloudwatch-agent`の表示が下記になった時は起動に失敗してます。
```
[ec2-user@ip-10-40-0-10 etc]$ sudo systemctl status amazon-cloudwatch-agent
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
   Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; disabled; vendor preset: disabled)
   Active: activating (auto-restart) (Result: exit-code) since Mon 2022-07-11 11:32:18 UTC; 2s ago
  Process: 4718 ExecStart=/opt/aws/amazon-cloudwatch-agent/bin/start-amazon-cloudwatch-agent (code=exited, status=1/FAILURE)
 Main PID: 4718 (code=exited, status=1/FAILURE)

Jul 11 11:32:18 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: amazon-cloudwatch-agent.service: main process exited, code=exited, status=1/FAILURE
Jul 11 11:32:18 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: Unit amazon-cloudwatch-agent.service entered failed state.
Jul 11 11:32:18 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: amazon-cloudwatch-agent.service failed.
```
原因は何ぞやという事で、ログを見ます。
```
[ec2-user@ip-10-40-0-10 etc]$ journalctl -u amazon-cloudwatch-agent
-- Logs begin at Mon 2022-07-11 09:41:05 UTC, end at Mon 2022-07-11 11:43:29 UTC. --
Jul 11 11:17:34 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: Started Amazon CloudWatch Agent.
Jul 11 11:17:34 ip-10-40-0-10.ap-northeast-1.compute.internal start-amazon-cloudwatch-agent[4395]: Valid Json input schema.
Jul 11 11:17:34 ip-10-40-0-10.ap-northeast-1.compute.internal start-amazon-cloudwatch-agent[4395]: I! Detecting run_as_user...
Jul 11 11:17:34 ip-10-40-0-10.ap-northeast-1.compute.internal start-amazon-cloudwatch-agent[4395]: 2022-07-11T11:17:34Z E! [telegraf] Error running agent: Error parsing /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.t
Jul 11 11:17:34 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: amazon-cloudwatch-agent.service: main process exited, code=exited, status=1/FAILURE
Jul 11 11:17:34 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: Unit amazon-cloudwatch-agent.service entered failed state.
Jul 11 11:17:34 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: amazon-cloudwatch-agent.service failed
```
ここで注目すべきは下記になります。
```
07-11T11:17:34Z E! [telegraf] Error running agent: Error parsing /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.t
```
これ、切れちゃってるんですが下記のエラーが出てるようです。

```
Error parsing /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml, open /usr/share/collectd/types.db: no such file or directory
```
/usr/share/collectd/types.dbがないと。確認するとそもそもディレクトリも無いです。
```
[ec2-user@ip-10-40-0-10 etc]$ ls /usr/share/collectd/types.db
ls: cannot access /usr/share/collectd/types.db: No such file or directory
[ec2-user@ip-10-40-0-10 etc]$ ls /usr/share/collectd/
ls: cannot access /usr/share/collectd/: No such file or directory
```
これ、ディレクトリと空ファイルをtouchで作ったら動いたんですが流石にまずい。
調べたら同様の事象の解決方法を書かれている方がいました

https://knhk.hatenablog.com/entry/2018/10/29/112956

空ファイル作った処置までは私と同じですが、コメント欄にcollectdをすればtypes.dbが作成されるとあります。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-custom-metrics-collectd.html

ためしにagentは停止して、空ファイルで作成したtypes.dbを削除しました。
ではcollectdを実行します。
```
[ec2-user@ip-10-40-0-10 etc]$ sudo amazon-linux-extras install collectd
Installing collectd
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Cleaning repos: amzn2-core amzn2extra-collectd amzn2extra-docker
14 metadata files removed
6 sqlite files removed
0 metadata files removed
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
~snip~
```
実行できたのでtypes.dbを確認します。
```
[ec2-user@ip-10-40-0-10 etc]$ cat /usr/share/collectd/types.db
absolute                value:ABSOLUTE:0:U
apache_bytes            value:DERIVE:0:U
apache_connections      value:GAUGE:0:65535
apache_idle_workers     value:GAUGE:0:65535
apache_requests         value:DERIVE:0:U
apache_scoreboard       value:GAUGE:0:65535
ath_nodes               value:GAUGE:0:65535
~snip~
```
作成されているし、中も空ではなくしっかりあります。
ではagentを起動してみます
```
[ec2-user@ip-10-40-0-10 etc]$ sudo systemctl restart amazon-cloudwatch-agent
[ec2-user@ip-10-40-0-10 etc]$ sudo systemctl status amazon-cloudwatch-agent
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
   Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2022-07-11 11:58:50 UTC; 3s ago
 Main PID: 5182 (amazon-cloudwat)
   CGroup: /system.slice/amazon-cloudwatch-agent.service
           └─5182 /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml -envconfig /opt/aws/amazon-cloudwatch-agent/etc/env-config.json -pidfile /o...

Jul 11 11:58:50 ip-10-40-0-10.ap-northeast-1.compute.internal systemd[1]: Started Amazon CloudWatch Agent.
Jul 11 11:58:50 ip-10-40-0-10.ap-northeast-1.compute.internal start-amazon-cloudwatch-agent[5182]: Valid Json input schema.
Jul 11 11:58:50 ip-10-40-0-10.ap-northeast-1.compute.internal start-amazon-cloudwatch-agent[5182]: I! Detecting run_as_user...
[ec2-user@ip-10-40-0-10 etc]$
```
起動しました。という訳でcloudwatchagentが起動しない時は`sudo amazon-linux-extras install collectd`を実行で解決しそうです。

原因ですが、どうやらAmazon Linux 2にcollectdが入ってないにもかかわらず設定ファイル(json)を作成した時にcollectdが必要なメトリクスを有効にしてたみたいです。

この部分
```
Do you want to monitor metrics from CollectD? WARNING: CollectD must be installed or the Agent will fail to start
1. yes
2. no
default choice: [1]:
```

下記のサイトさんでもうちょっと詳しく書かれてます。

https://dev.classmethod.jp/articles/amazon-linux-2-cloudwatch-agent-error-solution/

https://www.d-make.co.jp/blog/2021/03/29/cloudwatch%E3%82%A8%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%B3%E3%83%88%E3%81%A7%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E4%BD%BF%E7%94%A8%E7%8E%87%E3%81%AE%E5%8F%AF%E8%A6%96%E5%8C%96%E3%81%AE%E7%B0%A1%E5%8D%98/