📌

CloudWatchのメトリクスをスプレッドシートでグラフ化する

2023/07/30に公開

CloudWatchのメトリクスをスプレッドシートに貼り付けて中長期のモニタリングに使用したいという要件が出てきたので、AWS CLIでメトリクスを取得し、スプレッドシートにインポートしてグラフ化する手順を調べてみました。

結果、以下のようにCloudWatchのグラフと遜色ないものがスプレッドシートでも描けることがわかったので、下に手順を記載します。

CloudWatchのグラフ スプレッドシートでグラフ化
CloudWatchのグラフ スプレッドシートのグラフ

データを取得する際に使用するクエリの作成や、結果の整形にRubyを用いています。

メトリクスのデータを取得するAPI

一度に500個までのメトリクスを取得できるGetMetricDataを使用します。
このAPIを使用するAWS CLIのコマンドはget-metric-dataです。

これに似たAPIとしてGetMetricStatisticsがあります。
こちらのAPIの呼び出しはCloudWatchの無料利用枠に含まれますが、1度の呼び出しで1つのメトリクスしか取得できないので今回は使用しません。

GetMetricDataとGetMetricStatisticsの比較については、こちらの記事をご覧ください。

メトリクスを取得してグラフ化する手順

  1. 利用中のAWSアカウントで取得可能なメトリクスの一覧を取得する
  2. どのメトリクスを取得対象にするかを決める
  3. get-metric-dataに渡すJSONクエリを作成する
  4. get-metric-dataを実行する
  5. 実行結果のJSONをCSVに変換する
  6. CSVをスプレッドシートにインポートする
  7. インポートしたデータをグラフにする

手順詳細

1. 利用中のAWSアカウントで取得可能なメトリクスの一覧を取得する

list-metricsコマンドを実行して、利用中のAWSアカウントで取得可能なメトリクスの一覧を取得します。
teeコマンドを使用して標準出力とファイルの両方に出力しています。

aws cloudwatch list-metrics | tee metrics.json

コマンドの実行結果です。

{
    "Metrics": [
        {
            "Namespace": "AWS/ECS",
            "MetricName": "CPUUtilization",
            "Dimensions": [
                {
                    "Name": "ServiceName",
                    "Value": "my-server"
                },
                {
                    "Name": "ClusterName",
                    "Value": "my-cluster"
                }
            ]
        },
        // ... 省略 ...
    ]
}

2. どのメトリクスを取得対象にするかを決める

先ほど取得したメトリクス一覧のJSONをjqでクエリして、名前空間(Namespace)の中にどんなメトリクスがあるかを確認してみます。

以下のコマンド例では名前空間AWS/ECSのメトリクス一覧を取得しています。
Dimensionだけが異なる重複したメトリクスはuniqをかけて1つにまとめて出力しています。

cat metrics.json | \
jq -r '.Metrics[] | select(.Namespace == "AWS/ECS") | .MetricName' | \
sort | uniq

コマンドの実行結果です。

CPUUtilization
MemoryUtilization

上がCPU使用率、下がメモリ使用率のメトリクス名であることは明らかですね。

このように名前空間内のメトリクスの種類が少数かつ名前から何を表しているかが明らかな場合はよいのですが、そうでない場合もあります。
そのような場合は、以下のようにCloudWatchのグラフからメトリクス名をたどることができます。

下の画像のようにメトリクスのグラフの右上にあるメニューから「メトリクスで表示」をクリックします。

ECS CPU使用率

遷移先のCloudWatchメトリクスのページの「詳細」列に表示されている文字列をクリックすると、ポップアップが表示されメトリクス名("MetricName")を確認することができます。
また、「統計」列ではそのメトリクスがどんな種類の統計を表しているのかが確認できます。

CloudWatch Metrics

ポップアップ
CloudWatch Metrics ポップアップ

「統計」の代表的な値とJSONクエリに指定する"Stat"との対応関係は以下の通りです。

統計 クエリに指定する"Stat"の値
平均 Average
最大 Maximum
最小 Minimum
合計 Sum

サービスのページにないメトリクスについては、以下のメニューからどんなものがあるかを確認することができます。

  • CloudWatch > メトリクス > すべてのメトリクス

3. get-metric-dataに渡すJSONクエリを作成する

どのメトリクスを取得したいかが決まり、そのメトリクスのデータを取得する際にJSONクエリで指定する"MetricName", "Stat"もわかったので、クエリを作成することができます。

以下のRubyスクリプトをダウンロードしてエディタで開き、定数TARGET_METRICSに取得したいメトリクスを定義してください。
{ Namespace => { MetricName => [Stats] }} の形式で定義します。

また、定数PERIODに取得したいデータポイントの粒度を秒数で指定します。

https://github.com/ikoba/aws-getmetricdata-helper-scripts/blob/main/create_query.rb

編集ができたら以下のように実行します。

./create_query.rb metrics.json | tee query.json

実行が成功すると標準出力とquery.jsonに作成したクエリが出力されます。
実行権限がなくエラーになる場合は、以下のコマンドを実行してから再度実行してください。

chmod +x *.rb

4. get-metric-dataを実行する

手順3で作成したクエリを指定して以下のコマンドを実行し、メトリクスのデータを取得します。

aws cloudwatch get-metric-data \
  --metric-data-queries file://query.json \
  --start-time "2023-06-01T00:00:00+0900" \
  --end-time "2023-07-01T00:00:00+0900" \
  | tee result.json

以下の引数の指定は必須です。

引数 説明
--metric-data-queries クエリとなるJSONを文字列で指定します。
上のようにfile://をつけるとファイルを指定できます。
--start-time データ取得範囲の開始日時を指定します。
例)"2023-06-01T00:00:00+0900"
・日本時間を指定する場合は末尾に+0900を付けます。
--end-time データ取得範囲の終了日時を指定します。
例)"2023-07-01T00:00:00+0900"
・日本時間を指定する場合は末尾に+0900を付けます。
・データ取得範囲は以下のようにend-timeを含みません。
 start-time ≦ データ取得範囲 < end-time

引数の詳細については、こちらの公式ページ(英語)を参照してください。

実行が成功すると標準出力とresult.jsonに取得結果が出力されます。

5. 実行結果のJSONをCSVに変換する

手順4で取得したresult.jsonをスプレッドシートで読み込めるようにCSV形式のファイルに変換します。
まず、以下のRubyスクリプトをダウンロードしてください。

https://github.com/ikoba/aws-getmetricdata-helper-scripts/blob/main/json_to_csv.rb

以下のコマンドを実行します。result.csvが出力されます。

./json_to_csv.rb result.json | tee result.csv

CSV化する際に時系列のデータを上から下に並べるか、それとも左から右に並べるかの2パターンが考えられます。
前者の上から下に並べる場合は、スプレッドシートでグラフが作りやすいです。
データを表として見る場合は、後者の左から右に並べるパターンのほうがわかりやすいと思います。

上のjson_to_csv.rbは、前者のパターンで並べていますので、後者の並べ方がよい場合はスクリプトを修正してください(データをtransposeしている行を削除するだけです)。

6. CSVをスプレッドシートにインポートする

上の手順で出力されたresult.csvをスプレッドシートに読み込みます。

スプレッドシートのメニュー「ファイル > インポート」をクリックし、表示されるポップアップ「ファイルをインポート」のタブ「アップロード」に手順5で作成したresult.csvをドラッグします。

インポート後のスプレッドシート

インポートできました。

7. インポートしたデータをグラフにする

新しいシートを作成し、メニュー「挿入 > グラフ」をクリックします。
画面右側にグラフエディタが表示されるので、以下のように設定します。

設定項目 内容
グラフの種類 折れ線
データ範囲 (インポートしたデータのシートのヘッダー行を含むデータ範囲を指定)

メトリクスの数が多すぎて全範囲を指定しても「系列」で目的のメトリクスが指定できない場合があります。その場合は「データ範囲の選択」ダイアログで「別の範囲を追加」をクリックして、日時の列と目的のメトリクスのデータ範囲を別々に追加することができます。
X軸 Time
系列 (グラフに表示したいメトリクス)

試しにECSのCPU使用率の平均、最大、最小値をグラフ化してみました。

スプレッドシートのグラフ

CloudWatchのグラフと比較してみます。

CloudWatchのグラフ

縦横のスケールが少し違いますが、同じグラフが描けました!!

Discussion