Elastic Beanstalkでのメモリ使用率を監視する

Elastic Beanstalk の監視に関する以下2点について解説します。

* デフォルトのメトリクス以外の監視指標の追加方法
* しきい値設定し、超えた場合にSNSにアラートを飛ばす方法

## 前提条件

* プラットフォーム：Node.js 12 running on 64bit Amazon Linux 2

※Amazon Linux2ですが、古いAmazon Linuxでも設定方法は同じです。

## Beanstalkにおける監視
Elastic Beanstalkではアプリケーションをデプロイするだけでコンソールなどからデフォルトでいくつかの情報を得られます。
 
* インスタンス数
* CPU使用率
* ネットワークトラフィック量　など

![スクリーンショット_2020-11-17_18_25_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/1393a87e-7ba1-0d68-5ac6-3fa21afd3be7.png)

ただし、**メモリ使用率やディスク使用量のデータはデフォルト状態では取得できません**。。。

これらを取得するには、[.ebextensions](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ebextensions.html)を利用した設定が必要になります。

## デフォルト以外の指標を監視する
### メモリ使用率の取得
* [公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/customize-containers-cw.html#customize-containers-cw-update-roles)に設定方法が記載されています。またはAWSの公式サンプルとして[github](https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/resource-configuration/autoscaling-memory-utlization.config)でも公開されています。
* ドキュメントにある設定をそのままコピーして.ebextensions/cloudwatch.configとして作成（名前はxxx.configならOK）

```.ebextensions/cloudwatch.config
packages:
  yum:
    perl-DateTime: []
    perl-Sys-Syslog: []
    perl-LWP-Protocol-https: []
    perl-Switch: []
    perl-URI: []
    perl-Bundle-LWP: []

sources:
  /opt/cloudwatch: https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.1.zip

container_commands:
  01-setupcron:
    command: |
      echo '*/5 * * * * root perl /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl `{"Fn::GetOptionSetting" : { "OptionName" : "CloudWatchMetrics", "DefaultValue" : "--mem-util --disk-space-util --disk-path=/" }}` >> /var/log/cwpump.log 2>&1' > /etc/cron.d/cwpump
  02-changeperm:
    command: chmod 644 /etc/cron.d/cwpump
  03-changeperm:
    command: chmod u+x /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl

option_settings:
  "aws:autoscaling:launchconfiguration" :
    IamInstanceProfile : "aws-elasticbeanstalk-ec2-role"
  "aws:elasticbeanstalk:customoption" :
    CloudWatchMetrics : "--mem-util --mem-used --mem-avail --disk-space-util --disk-space-used --disk-space-avail --disk-path=/ --auto-scaling"
```

* この設定を追加した状態でデプロイすると、モニタリングのコンソールで以下のような項目が新たに選べるようになります。
    * Memory Utilization（メモリ使用率）
    * Memory Available（メモリ残量）
    * Memory Used（メモリ使用量）

![100959623-0a408600-3562-11eb-8c06-c18413fe5e63.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/e64b1d7d-4779-bb4d-9e84-c702d54edfd3.png)

### ※2021年6月14日追記
そのままコピーすると現在perl-Digest-SHAのインストールでエラーが出ます。解決策としてはこちらの[イシュー](https://github.com/awsdocs/elastic-beanstalk-samples/issues/109#issuecomment-622834041)の通り、perl-Digest-SHA.x86_64を指定することです。


## SNSにアラートを飛ばす
* しきい値を設定し、超えた場合にSNSにアラートを飛ばすには、こちらも.ebextensionsに設定ファイルを追加します。
* 書式はyamlで、実態としてはCloudFormationの設定ファイルです。そのため、各設定項目の詳細は[Cloudformationのドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html)で参照できます。
* 以下はCPU使用率が50%以上になった場合にSNSにアラートを飛ばす設定例です。

```.ebextensions/create_alarm.config
Resources:
  CPUAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
      - arn:aws:sns:ap-northeast-1:xxxxxxxxx:xxxxxxxxxxx
      MetricName: CPUUtilization
      ComparisonOperator: GreaterThanOrEqualToThreshold
      AlarmDescription: { "Fn::Join" : ["", [{ "Ref" : "AWSEBEnvironmentName" }, "-CPU-utilization-alarm." ]]}
      Statistic: Average
      Period: 60
      Dimensions:
      - Value:
          Ref: AWSEBAutoScalingGroup
        Name: AutoScalingGroupName
      EvaluationPeriods: 1
      InsufficientDataActions: []
      Namespace: AWS/EC2
      OKActions:
      - arn:aws:sns:ap-northeast-1:xxxxxxxxx:xxxxxxxxxxxxx
      Threshold: 50
```

### アラームの設定ファイルを簡単に作成する方法
* CloudFormationの設定ファイルを一から作成するのは大変ですが、一度テスト環境などでBeanstalkの画面からアラームを設定し、EB CLIの[config saveオプション](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb3-config.html)を使うと現在の環境の設定をファイル出力できます。
* アラームをコンソールから設定
![スクリーンショット_2020-11-17_18_54_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/61aa82d1-e26c-a137-e3fa-5ad14bf4e596.png)


* 設定をコマンドで出力

```
eb config save 
```
出力されたファイルのアラーム設定の部分をコピーし、.ebextensions/xxx.configとして追加すればOKです。

## 参考
* [メモリ使用量の取得方法についての公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/customize-containers-cw.html#customize-containers-cw-update-roles)
* [Amazon EC2 インスタンスで実行中の Amazon Linux AMI 用 Elastic Beanstalk でメモリ使用料をモニタリングするにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/elastic-beanstalk-memory-monitoring/?nc1=h_ls)