AWSでプロセス監視を実装したい

# はじめに
AWSでサービス監視を実装して、サービスの正常性を監視してみました。

# 前提条件
- EC2インスタンスが構築されていること（今回はAmazon Linux2を使用します）
- パブリックサブネットへ接続するインターネットゲートウェイはアタッチ済みであること
- サービスの正常性を確認する対象はApache(httpd)とします
- CloudWatchエージェントが導入済みであること。
（入れていない場合は、導入方法も別で記載していますのでご確認ください）

[【導入手順】 AWSでCloudWatchエージェントを入れてみた](https://qiita.com/santasan1224/items/1dc5214d119ea3b9815e)

# 構成図
![CWSAgent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/c3dbf1f7-793e-d980-d72c-89ee1d28132e.png)

今回は「httpdを監視して、プロセス数が0になったらEC2インスタンスを再起動する」という実装にします。

大まかな流れとしては
1. サービス監視用のCloudWatch Agentの設定ファイルを作成する
2. 設定ファイルをSSMで反映する
3. CloudWatch上でhttpdのプロセスが取れているか確認する
4. httpdプロセス用のCloudWatchアラームを作成する
5. Apache停止を行ってアラームが発砲されているか確認する
6. EC2インスタンスが再起動していることを確認する

# 実際にやってみた
### サービス監視用のCloudWatchエージェントの設定ファイルを作成
特定のプロセスを監視するための設定ファイルを作成します。設定ファイルはSSMのパラメータストアに格納します。

SSMからパラメータストアへ移動しパラメータの作成をクリックします。
パラメータの詳細は以下の通りで記述していきます。

```
名前：後で使用するので判別しやすい名前にしておくと良いです
説明：説明文を入力する
利用枠：標準
タイプ：文字列
データ型：text
値：{
    "metrics": {
        "metrics_collected": {
            "procstat": [
                {
                    "exe": "httpd",
                    "measurement": [
                        "pid_count"
                    ],
                    "metrics_collection_interval": 60
                }
            ]
        }
    }
}
```

値について簡単に説明します。
・exe ：プロセス名を記述します。今回はhttpdを監視するので"httpd"を記述する
Linuxサーバで設定する"exe"セクションでは、指定した文字列に対して全て正規表現で読み取りますので、ワイルドカードを使用して複数のプロセスを指定することも可能です。
・pid_count ：プロセスが起動している数。今回はhttpdのプロセス数を読み取ります。
・metrics_collection_interval ：対象のメトリクスを収集する間隔を指定します。httpdプロセスを収集する間隔はデフォルトの"60秒"としておきます。（ちなみにこのセクションは省略可能です）


※exeの設定の仕方について、公式ドキュメントに記載されています。
exe以外の方法もありますので、要求内容に合わせて設定ください。
[procstat プラグインでプロセスメトリクスを収集する](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-procstat-process-metrics.html)

### 設定ファイルを反映する
設定したファイルをCloudWatchエージェントに反映していきます。

SSMから"Run Command"を選択してコマンドパラメータは以下の通り入力します。
・Action：Configure(Append)　　既に反映されているパラメータが存在するのでそれに追記します
・Mode：ec3
・Optional Configuration Source：ssm
・Optional Configuration Location：httpd-proc-collector　　先ほど作成した設定ファイル名を入力
・Optional Open Telemetry Collector Configuration Source：ssm
・Optional Open Telemetry Collector Configuration Location：未記入
・Optional Restart：yes

![スクリーンショット 2021-07-24 10.36.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/252f58db-413c-8779-23bb-cc941cdc2a0d.png)

ターゲットは対象のインスタンスを指定します。
![スクリーンショット 2021-07-24 10.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/a7aeb66a-df31-4b22-7bd4-f17e01481f7c.png)

その他はデフォルトで実行すると実行結果が出力されます。
![スクリーンショット 2021-07-24 10.37.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/6c6c7683-a071-d7cd-b7ce-d8e72ddf663d.png)

ターゲットと出力のインスタンスIDをクリックして中身を確認しましょう。
![スクリーンショット 2021-07-24 10.38.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/d73a8a26-ceb5-094f-6d52-cb6e5106ef87.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:httpd-proc-collector --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml --multi-config append
Region: ap-northeast-1
credsConfig: map[]
Successfully fetched the config and saved in /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_httpd-proc-collector.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 append
/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json does not exist or cannot read. Skipping it.
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
```

「Error」

```
2021/07/24 14:52:44 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json ...
2021/07/24 14:52:44 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_AmazonCloudWatch-linux ...
2021/07/24 14:52:44 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_httpd-proc-collector.tmp ...
Redirecting to /bin/systemctl stop amazon-cloudwatch-agent.service
Redirecting to /bin/systemctl restart amazon-cloudwatch-agent.service
```

サービスを再起動したログみたいなのでエラー出力ではありませんね。
設定ファイルの読み込みも成功しているのでこのまま先へ進めます。


### CloudWatchのメトリクスを確認
CloudWatch画面に移動して「メトリクス」をみてみましょう。
「CWAgent」から「ImageId,InstanceId,InstanceType,exe,pid_finder」というディメンションがありその中に対象のメトリクスが存在しています。
![スクリーンショット 2021-07-25 9.42.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/7e9247f9-f716-b4c1-1924-0e012189d74f.png)

対象のメトリクスが取れていますね。
プロセスが7つあるみたいです。念のためサーバへログインして確認してみましょう。

```
[ec2-user@ip-10-0-1-10 ~]$ ps -ef | grep httpd
root      2798     1  0 00:30 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2829  2798  0 00:30 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2830  2798  0 00:30 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2831  2798  0 00:30 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2832  2798  0 00:30 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2833  2798  0 00:30 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    3184  2798  0 00:33 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
ec2-user  3368  3343  0 00:43 pts/1    00:00:00 grep --color=auto httpd
[ec2-user@ip-10-0-1-10 ~]$ 
```

最下行の"ec2-user"が起動しているもの以外がhttpdプロセスで合計7つで合っていますね。

# アラームを発泡させてみる
### まずアラームを作成する
CloudWatchの「アラーム」へ移動し、「メトリクスの選択」をクリックしましょう。
そして、先ほど確認したメトリクスにチェックを入れて「メトリクスの選択」をクリック。
![スクリーンショット 2021-07-25 9.51.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/52e8eda3-1ce9-f669-bc3f-35896a4fa1d5.png)

「メトリクスと条件の指定」では以下の条件で入力します。
期間のデフォルトは"5分"なので、今回は検証するためで短い間隔で実施します。
![スクリーンショット 2021-07-25 9.54.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/41487793-7da1-04bb-2e10-543ed13749bf.png)

「条件」
・しきい値の種類：静的
・アラーム条件：より低い
・しきい値：1
・アラームを実行するデータポイント：1/1
・欠落データの処理：欠落データを不正(しきい値を超えている)として処理

![スクリーンショット 2021-07-25 10.02.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/802a5810-48af-e04d-009b-df02bc5554dc.png)

「通知」
・アラーム状態のトリガー：アラーム状態
・SNSトピックの選択：お使いのアカウントに合わせて設定ください
（今回は既存のSNSトピックを使っています。エンドポイントは自分のメールアドレスです。）

![スクリーンショット 2021-07-25 10.10.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/e423318d-977f-e982-7e7f-a26abd9e0ed3.png)

「EC2アクション」
・アラーム状態トリガー：アラーム状態
・アクション：このインスタンスの再起動
今回の要件はプロセスが停止した時にアラームが発生してEC2が再起動するかを確認することでしたので
上記のようにします。

![スクリーンショット 2021-07-25 10.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/1a52f4d4-b611-9f26-6fb3-1a338fd03a9f.png)

「名前」
![スクリーンショット 2021-07-25 10.16.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/5ba17d65-c6c4-f546-7902-bd81440509d0.png)

最終確認画面が出るので、問題がなければアラームを作成しましょう。

![スクリーンショット 2021-07-25 10.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/baa908c9-d9a1-5350-8a1a-83fe9467d9dd.png)

アラームが作成されて正常値確認ができていますね。

### プロセスを停止してみる
まずはサーバへログインし、httpdを停止しましょう。

```
[root@ip-10-0-1-10 ~]# systemctl stop httpd.service 
[root@ip-10-0-1-10 ~]# systemctl status httpd.service 
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Sun 2021-07-25 01:20:42 UTC; 5s ago
     Docs: man:httpd.service(8)
  Process: 2798 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=0/SUCCESS)
 Main PID: 2798 (code=exited, status=0/SUCCESS)
   Status: "Total requests: 1; Idle/Busy workers 100/0;Requests/sec: 0.000335; Bytes served/sec:   1 B/sec"

Jul 25 00:30:49 ip-10-0-1-10.ap-northeast-1.compute.internal systemd[1]: Star...
Jul 25 00:30:49 ip-10-0-1-10.ap-northeast-1.compute.internal systemd[1]: Star...
Jul 25 01:20:41 ip-10-0-1-10.ap-northeast-1.compute.internal systemd[1]: Stop...
Jul 25 01:20:42 ip-10-0-1-10.ap-northeast-1.compute.internal systemd[1]: Stop...
Hint: Some lines were ellipsized, use -l to show in full.
[root@ip-10-0-1-10 ~]# 
[root@ip-10-0-1-10 ~]# ps -ef | grep httpd
root      3970  3923  0 01:21 pts/2    00:00:00 grep --color=auto httpd
[root@ip-10-0-1-10 ~]# 
```

### アラームを確認する
アラームを確認するとアラームが発生していますね。
![スクリーンショット 2021-07-25 10.22.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/8996559d-7210-4d3b-92a9-b8c12643283f.png)

アラーム発生直後は、インスタンスへのSSH接続が切れていますので、再起動が成功していますね。

```
[root@ip-10-0-1-10 ~]# date
Sun Jul 25 01:22:21 UTC 2021
[root@ip-10-0-1-10 ~]# Connection to 54.95.39.151 closed by remote host.
Connection to 54.95.39.151 closed.
```

メールも通知できています。
![スクリーンショット 2021-07-25 10.26.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/011d925d-4b0e-e069-7d65-08224f59581c.png)

起動も確認できました。
![スクリーンショット 2021-07-25 10.27.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/b7e39c65-c295-4d0c-fd3f-8a972496bde6.png)

メトリクスも正常値に復旧しました。
![スクリーンショット 2021-07-25 10.28.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478546/3e1b69a3-6c56-8ae9-a583-36724d3043b6.png)