本記事は 
オブザーバビリティウィーク 
4日目の記事です。
💻📄 
3日目
 ▶▶ 本記事 ▶▶ 
5日目
 🔔🏢

はじめに
オブザーバビリティウィーク4日目を担当させていただきます。北野と申します。 現在の業務ではクラウドサービス(AWS)を用いたお客様のアプリケーション実行基盤の構築、運用・保守を主として行っております。 インフラの運用を行っていると障害発生時の状況をレポーティングするといったシーンが度々あると思います。 今回はその際の有効な手法をご紹介します。
想定するシーン
- 障害発生当時のAmazon CloudWatchメトリクスのグラフを用いたレポートをドキュメントとして作成することになった。
 - レポートには障害に関連するAmazon CloudWatchメトリクスのグラフを発生時の状態でスクリーンショットを取得して貼り付ける必要がある。
 - 今後も障害が発生した際はこの作業を実施する必要がある。
 
解決したい課題
- グラフのスクリーンショットを手動で取得すると、大きさが統一されない。
 - メトリクスの条件を一つ一つ手動で変更していると時間がかかり、またミスが発生しやすい。
 - 一度実施したAmazon CloudWatch操作を繰り返したくない。
 
そこでMetricWidgetを活用しませんか?

MetricWidgetとは、Amazon CloudWatchの発行元タブをクリックすると表示されるJSONデータです。 このJSONデータの中には現在表示されているメトリクスのグラフに関する様々な情報が含まれており、こちらの内容とAmazon CloudWatchのAPIを組み合わせれば、上記のような煩雑な作業を効率的に実施することができます。
MetricWidgetの利点
Amazon CloudWatchのMetricWidgetを活用することで、以下のような利点があります。
- 一度作成したグラフのMetricWidgetを取得しておけば設定を復元できます。
 - JSON形式なので、gitで履歴管理したり、内容の変更をスクリプトなどから動的に行うことができます。
 
MetricWidgetからグラフのスクリーンショットを取得する方法
以下ではpython、Amazon CloudWatchのget_metric_widget_image API、MetricWidgetを用いてグラフのスクリーンショットを取得する方法を紹介します。
使用した言語のバージョン・パッケージ
python 3.13.2 boto3 1.38.41 botocore 1.38.41 pillow 11.2.1
参考:get_metric_widget_image API docs.aws.amazon.com
作業のアウトライン
- マネジメントコンソールからAmazon CloudWatchのMetricWidgetを取得しJSONファイルとして保存する。
 - pythonコードを用いて上記のJSONからグラフのスクリーンショットを取得する。
 
Amazon CloudWatchのMetricWidgetを取得
マネジメントコンソールにてAmazon CloudWatchを表示し取得したいグラフをまず表示させます。

画面下部のタブから「発行元」タブを選択します。

「イメージAPI」のチェックボックスをクリックします。(この操作によって、グラフのスクリーンショットに適した内容を取得できます。)

「コピー」をクリックするとクリップボードに表示されているJSONデータの内容が保存されます。ファイルとして保存しておきましょう。(ここではtemplate.jsonという名前で保存します。)

取得したJSONデータの項目を見てみましょう。
{
    "view": "timeSeries",
    "stat": "Average",
    "period": 300,
    "stacked": false,
    "yAxis": {
        "left": {
            "min": 0
        }
    },
    "metrics": [
        [ "AWS/EC2", "CPUUtilization", "InstanceId", "i-XXXXX", { "label": "i-XXXXX ", "region": "us-west-2" } ]
    ],
    "title": "CPU Utilization (%)",
    "width": 1382,
    "height": 291,
    "start": "2025-06-20T15:00:00.000Z",
    "end": "2025-06-21T14:59:59.000Z",
    "timezone": "+0900"
}
各項目の概要は以下です。
| 項目名 | 説明 | 
|---|---|
| view | グラフの表示形式。ここでは「timeSeries」として、時系列グラフを表示します。 | 
| stat | 表示する統計情報。ここでは「Average」として、平均値を表示します。 | 
| period | データの収集間隔。ここでは300秒(5分)ごとにデータを収集します。 | 
| stacked | 積み上げグラフか通常のグラフかを設定するflag。ここでは通常のグラフを表示します。 | 
| yAxis | y軸の設定。左側のy軸の最小値を0に設定しています。 | 
| metrics | グラフに表示されるメトリクスの設定。ここでは、EC2インスタンスのCPU使用率を表示します。 | 
| title | グラフのタイトル。ここでは「CPU Utilization (%)」として、グラフの内容を示しています。 | 
| width | 画像の幅 | 
| height | 画像の高さ | 
| start | データの開始日時 | 
| end | データの終了日時 | 
| timezone | タイムゾーン。ここでは「+0900」として、日本標準時(JST)を示しています。 | 
画像の幅、高さ、データの開始・終了など必要に応じて上記の項目を編集することで、活用の幅が広がります。
pythonを使用したグラフのスクリーンショットの自動取得
必要なライブラリをインストールします。
pip install pillow boto3
以下のコードを実装します。(main.py)
import json
import boto3
import io
from PIL import Image
 
# boto3でセッションを作成
cw_client = boto3.client("cloudwatch")
 
# MetricWidgetのJSONファイルを読み込み
with open("template.json", "r") as f:
    widget = json.load(f)
# get_metric_widget_imageメソッドにMetricWidgetの内容を渡す
response = cw_client.get_metric_widget_image(MetricWidget=json.dumps(widget))
 
# 画像データが返却されるのでファイルとして保存する
image_bin = io.BytesIO(response["MetricWidgetImage"])
img = Image.open(image_bin)
img.save("graph.png", "PNG")
以下のコマンドで実行します。
python main.py
graph.pngという名前でグラフのスクリーンショットが画像ファイルとして出力されます。
まとめ
MetricWidgetはAmazon CloudWatchの意外と役に立つ機能です。こちらの機能を駆使すれば例えば以下のような応用も可能です。
- データの開始・終了を動的に設定して、グラフのスクリーンショットを取得する。
 - 取得したグラフのスクリーンショットをチャットツールで通知する。
 
ぜひMetricWidgetの活用を試してみてください!