AWS CloudShell でインスタンスのメモリ値を取得してみる

# この記事でやったこと
aws cli の get-metric-statistics を使用してインスタンスのメモリ値を取得する
```shell:投入コマンド(InstanceIDの i-12345678910 だけ直して利用してください)
aws cloudwatch get-metric-statistics \
  --metric-name mem_used_percent \
  --namespace CWAgent \
  --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ" -d "1 day ago") \
  --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --period 300 \
  --statistics Maximum \
  --dimensions Name=InstanceId,Value=i-12345678910 \
   | egrep "Maximum|Timestamp" | sed -z s/\",\\n/\"/g \
   | sort \
   | sed -e 's/ //g' -e 's/"/ /g' -e 's/:00+00:00//g'
```
```shell:出力結果
 Timestamp : 2022-05-23T23:33  Maximum :23.9299799416661,
 Timestamp : 2022-05-23T23:38  Maximum :24.191610383821548,
 Timestamp : 2022-05-23T23:43  Maximum :24.430953788311903,
 Timestamp : 2022-05-23T23:48  Maximum :24.587932053605172,
 Timestamp : 2022-05-23T23:53  Maximum :24.63395963139178,
 Timestamp : 2022-05-23T23:58  Maximum :28.066647932635007,
 Timestamp : 2022-05-24T00:03  Maximum :23.365536487756664,
 Timestamp : 2022-05-24T00:08  Maximum :23.39024602951579,
 Timestamp : 2022-05-24T00:13  Maximum :23.381040513958467,
 Timestamp : 2022-05-24T00:18  Maximum :23.39557553852266,
 Timestamp : 2022-05-24T00:23  Maximum :23.380071512320857,
 Timestamp : 2022-05-24T00:28  Maximum :23.80449422959525,
 Timestamp : 2022-05-24T00:33  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:38  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:43  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:48  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:53  Maximum :23.65962848477214,
```

# 目次
1. [この記事でやったこと](#この記事でやったこと)
1. [実装背景](#実装背景)
1. [cliでメトリクスの値を取得するためには？](#cliでメトリクスの値を取得するためには)
1. [GetMetricDataを使用してメモリの値を取ってみる](#getmetricdataを使用してメモリの値を取ってみる)
1. [GetMetricStatisticsを使用してメモリの値を取ってみる1](#getmetricstatisticsを使用してメモリの値を取ってみる1)
1. [GetMetricStatisticsを使用してメモリの値を取ってみる2](#getmetricstatisticsを使用してメモリの値を取ってみる2)
1. [GetMetricStatisticsを使用してメモリの値を取ってみる3](#getmetricstatisticsを使用してメモリの値を取ってみる3)
1. [GetMetricStatisticsを使用してメモリの値を取ってみる4](#getmetricstatisticsを使用してメモリの値を取ってみる4)
1. [GetMetricStatisticsを使用してメモリの値を取ってみる5](#getmetricstatisticsを使用してメモリの値を取ってみる5)
1. [GetMetricStatisticsを使用してメモリの値を取ってみる6](#getmetricstatisticsを使用してメモリの値を取ってみる6)
1. [GetMetricStatisticsを使用してメモリの値を取ってみる7](#getmetricstatisticsを使用してメモリの値を取ってみる7)
1. [おわり](#おわり)

# 実装背景
CloudWatch のメモリ使用率超過のメールを受ける場合、使用率を超過したってメールしかこない。
その為、どの程度の数値で検知したのかメールからだけでは読み取れず不便。
とりあえず aws cli を叩いてメモリ使用率を確認できるようにしてみた。
(現時点で未実装だが、cli の結果をメールに付与する予定)

# cliでメトリクスの値を取得するためには？
ググった感じだと「GetMetricData」「GetMetricStatistics」のどちらかのオプションを指定したら取得できそう！
https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudwatch-getmetricdata-api/
を見ると<font color="DeepPink"> GetMetricData </font>を推奨していました。
|![2022-05-24_101053.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/6e4eb82e-721b-1289-194a-146d8b50cea5.png)|
|:-:|

# GetMetricDataを使用してメモリの値を取ってみる
どうやったら取れるんだろ？と上記を見ていると、かなり細かくパラメータを指定しないといけないみたい。
<font color="DeepPink"> (jsonを長々用意とか非常に面倒くさい・・・) 
GetMetricData での取得は見送りました。
GetMetricStatistics で値を取得しようと思います。</font>

# GetMetricStatisticsを使用してメモリの値を取ってみる1

```shell:とりあえず取得したいメトリクス名を入れて叩いてみる
aws cloudwatch get-metric-statistics --metric-name mem_used_percent
```

```shell:出力結果
aws: error: the following arguments are required: --namespace, --start-time, --end-time, --period
```
--namespace, --start-time, --end-time, --period とかのオプションが足りないみたいでエラーになりました。


# GetMetricStatisticsを使用してメモリの値を取ってみる2

```shell:--namespace を指定してみる
aws cloudwatch get-metric-statistics \
 --metric-name mem_used_percent \
 --namespace CWAgent
```
```shell:出力結果
aws: error: the following arguments are required: --start-time, --end-time, --period
```
エラーから --namespace の部分が消えましたね


# GetMetricStatisticsを使用してメモリの値を取ってみる3
--start-time と --end-time を指定しないといけないみたいだけどどう指定するんでしょう？
今更ですが AWS CLI Command Reference をチラ見します。
https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/get-metric-statistics.html?highlight=getmetricstatistics
|![2022-05-24_104058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/b166d689-8b22-ba34-e081-1b76511824e1.png)|
|:-:|

例として 2016-10-03T23:00:00Z とあるので、こんな感じで指定する必要がありそうですね。
(最後のZはUTCで出力しているよ！という意味)

```shell:--start-time と --end-time を指定してみる
aws cloudwatch get-metric-statistics \
 --metric-name mem_used_percent \
 --namespace CWAgent \
 --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ" -d "1 day ago") \
 --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ")
```
```shell:出力結果
aws: error: the following arguments are required: --period
```
エラーが --period のみになりました。

# GetMetricStatisticsを使用してメモリの値を取ってみる4
--period って何を入れるの？
AWS CLI Command Reference を見る感じデータの粒度のようですね。
監視間隔が5分だったので、私は300と指定しておきました。
```shell:--period を指定してみる
aws cloudwatch get-metric-statistics \
 --metric-name mem_used_percent \
 --namespace CWAgent \
 --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ" -d "1 day ago") \
 --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
 --period 300
```
```shell:出力結果
An error occurred (InvalidParameterCombination) when calling the GetMetricStatistics operation: At least one of the parameters Statistics and ExtendedStatistics must be specified.
```
言われた通りにしてたのに何故かエラーが出ました(^q^？)
Statistics か ExtendedStatistics を指定して欲しいようです。
欲しがりさんのようですね。

# GetMetricStatisticsを使用してメモリの値を取ってみる5
--statistics や --extended-statistics って何を入れるの？
AWS CLI Command Reference を見る感じ統計情報のようですね。
--statistics では以下の5つが利用可能なようです。
|![2022-05-24_112319.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/31b14f23-a68e-ba71-3467-6486a84394bc.png)|
|:-:|

今回は --statistics を利用し、Maximum を指定します。
```shell:--statistics に Maximum を指定してみる
aws cloudwatch get-metric-statistics \
 --metric-name mem_used_percent \
 --namespace CWAgent \
 --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ" -d "1 day ago") \
 --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
 --period 300 \
 --statistics Maximum
```
```shell:出力結果
{
    "Label": "mem_used_percent",
    "Datapoints": []
}
```
まさかの何も出てこず(^q^？)

# GetMetricStatisticsを使用してメモリの値を取ってみる6
AWS CLI Command Reference を眺めているとdimensions を指定している例ばかりです。
試しに dimensions を指定してみようと思います。
dimensions は各自コマンドで確認しましょう。
```shell
aws cloudwatch list-metrics --metric-name mem_used_percent
```
```shell:出力結果の一部抜粋
{
        {
            "Namespace": "CWAgent",
            "MetricName": "mem_used_percent",
            "Dimensions": [
                {
                    "Name": "InstanceId",
                    "Value": "i-12345678910"
                }
            ]
        }
}
```
上記の出力の場合の Dimensions は以下となります。
--dimensions Name=InstanceId,Value=i-12345678910

```shell:参考
{
        {
            "Namespace": "CWAgent",
            "MetricName": "mem_used_percent",
            "Dimensions": [
                {
                    "Name": "InstanceId",
                    "Value": "i-12345678910"
                },
                {
                    "Name": "InstanceType",
                    "Value": "t2.micro"
                }
            ]
        }
}
```
もし上記のように複数でた場合の Dimensions は以下となります。
--dimensions Name=InstanceId,Value=i-12345678910 Name=InstanceType,Value=t2.micro
```shell:--dimensionsを指定してみる
aws cloudwatch get-metric-statistics \
  --metric-name mem_used_percent \
  --namespace CWAgent \
  --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ" -d "1 day ago") \
  --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --period 300 \
  --statistics Maximum \
  --dimensions Name=InstanceId,Value=i-12345678910
```
```shell:出力結果(一部抜粋)
{
    "Label": "mem_used_percent",
    "Datapoints": [
<snip>
        {
            "Timestamp": "2022-05-24T00:50:00+00:00",
            "Maximum": 23.666895997054237,
            "Unit": "Percent"
        },
        {
            "Timestamp": "2022-05-23T23:40:00+00:00",
            "Maximum": 24.423201775211,
            "Unit": "Percent"
        },
        {
            "Timestamp": "2022-05-24T00:15:00+00:00",
            "Maximum": 23.381040513958467,
            "Unit": "Percent"
        },
}
```
値がやっと取得できました！
ズラズラ出てきたけど、Timestanmp がグチャグチャな感じに見えますね(^q^？)

# GetMetricStatisticsを使用してメモリの値を取ってみる7
並び替える方法が分からなかったので、Linuxコマンドでゴリ押し。
egrep で Maximum か Timestamp に合致する行を出力。
sed にて ",改行 の箇所を " だけに置換。
sort で並び替え。
sed で改めていらなさそうな箇所を何もなしに置換。
```shell:
aws cloudwatch get-metric-statistics \
  --metric-name mem_used_percent \
  --namespace CWAgent \
  --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ" -d "1 day ago") \
  --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --period 300 \
  --statistics Maximum \
  --dimensions Name=InstanceId,Value=i-12345678910 \
   | egrep "Maximum|Timestamp" | sed -z s/\",\\n/\"/g \
   | sort \
   | sed -e 's/ //g' -e 's/"/ /g' -e 's/:00+00:00//g'
```
```shell:出力結果
 Timestamp : 2022-05-23T23:33  Maximum :23.9299799416661,
 Timestamp : 2022-05-23T23:38  Maximum :24.191610383821548,
 Timestamp : 2022-05-23T23:43  Maximum :24.430953788311903,
 Timestamp : 2022-05-23T23:48  Maximum :24.587932053605172,
 Timestamp : 2022-05-23T23:53  Maximum :24.63395963139178,
 Timestamp : 2022-05-23T23:58  Maximum :28.066647932635007,
 Timestamp : 2022-05-24T00:03  Maximum :23.365536487756664,
 Timestamp : 2022-05-24T00:08  Maximum :23.39024602951579,
 Timestamp : 2022-05-24T00:13  Maximum :23.381040513958467,
 Timestamp : 2022-05-24T00:18  Maximum :23.39557553852266,
 Timestamp : 2022-05-24T00:23  Maximum :23.380071512320857,
 Timestamp : 2022-05-24T00:28  Maximum :23.80449422959525,
 Timestamp : 2022-05-24T00:33  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:38  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:43  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:48  Maximum :23.666895997054237,
 Timestamp : 2022-05-24T00:53  Maximum :23.65962848477214,
```
(見栄えを綺麗にする魔改造はまだまだ出来そうだけど、とりあえず今はやらない)


# おわり
今回はメトリクス1つを指定して値を取りにいきました。
複数メトリクスを取得したい場合には GetMetricData が必要になりますし
json を予め用意できればそれを指定するだけなので、今の確認方法よりも楽になりそうですね。