🤖

AWS DashBoardからメトリクス画像を取得する

2023/04/15に公開

はじめに

AWS DashBoardから画像を取得したかったので、スクリプトを作成してみました。
credentialsから情報を取得し、ダッシュボードからウィジェットのjsonを取得し整形後、PNGを取得
します。
自分の場合は、月初めに前月の期間分を取得するようにしてます。

環境

aws-cli: 1.18.147
os: 4.14.299-223.520.amzn2.x86_64

準備

ダッシュボード及び保存用のS3を作成しておいてください。

必要な権限は、下記です。

・cloudwatch:GetDashboard
・cloudwatch:ListDashboards
・cloudwatch:GetMetricWidgetImage
・s3:PutObject

アクセスキーを登録します。

vim ~/.aws/credentials
[profile example]
aws_access_key_id = xxx
aws_secret_access_key = xxx
vim ~/.aws/config
[profile example]
output = json
region = ap-northeast-1

スクリプトを配置します。
DASHBOARD_NAME S3_PROFILE S3_NAME は適宜変更してください。
冒頭にも記載したように、前月を時間範囲指定しています。

vim ~/get-image-dashboard.sh
#!/bin/bash

#実行位置固定
cd `dirname $0`

#フォルダ生成 
mkdir -p ~/image_dir/ && cd ~/image_dir/

# credentials から profile に指定する名前を取得
PROFILE_LIST=(`cat ~/.aws/credentials | grep "\[" | sed -e 's/\[//g' -e 's/\]//g'`)
echo "================="
echo "PROFILE_LIST"
echo $PROFILE_LIST
echo "================="
# dashboard名を指定
DASHBOARD_NAME="example-board"
# s3保存先 profile
S3_PROFILE="S3_EXAMPLE"
# s3 bucket名
S3_NAME="example-bucket" 

#画像の width height を指定 
width_size=1200
height_size=800

# 時間範囲を指定 前月の月初め と 今月の月初め 自動入力 (入力値は -0900 した値となる Timezoneで加算される)
Year=$(date '+%Y')
Mon=$(date '+%m')
Day=1
#Hour="00"
#Min="00"
#Sec="00"

# 時間範囲を指定
from_time=$(date -d "$Year/$Mon/$Day 15:00:00 1month ago 1days ago" "+%Y-%m-%dT%H:%M:%S.%N" | cut -c1-23 | sed 's/$/Z/')
to_time=$(date -d "$Year/$Mon/$Day 15:00:00 1days ago" "+%Y-%m-%dT%H:%M:%S.%N" | cut -c1-23 | sed 's/$/Z/')

echo 'from: ' ${from_time}
echo 'to: ' ${to_time}

for profile_name in "${PROFILE_LIST[@]}"
do
  echo "======================="
  echo "profile_name:${profile_name} 実行中..."
  widgets_len=0

  # 必要な場合profile_name毎にフォルダを作成
  mkdir -p ~/image_dir/${profile_name}
  #widgetsの要素数取得
  widgets_len=$(aws cloudwatch get-dashboard  --dashboard-name ${DASHBOARD_NAME}  --profile ${profile_name} | jq '.DashboardBody' | sed -e 's/^"//' | sed -e 's/"$//' | sed -e 's/\\//g' | jq '.widgets | keys | length')
  echo "widgets_len:${widgets_len}"
  
  # dashboard widgetsからjsonを取得し、整形しPNG取得する
  for ((i=0; i<${widgets_len}; i++));
  do
    # dashboard json
    aws cloudwatch get-dashboard --dashboard-name ${DASHBOARD_NAME} --profile ${profile_name} | jq '.DashboardBody' | sed -e 's/^"//' | sed -e 's/"$//' | sed -e 's/\\//g' | jq '.widgets['$i'].properties' | jq '. |= .+{"width": '${width_size}',"height": '${height_size}',"start": "'${from_time}'","end": "'${to_time}'", "timezone": "+0900"}' > result_${profile_name}_${i}.json
    echo
    #title から値を取り、変数に入れて、画像名に使う title 空白削除
    image_name=$(cat result_${profile_name}_${i}.json | jq -r '.title' | sed -e 's/ //g')
    #titleがnullの場合
    if [ -z "${image_name}" ]; then
      random_value=`cat /dev/urandom | tr -dc '[:digit:]'| head -c 3`
      image_name=null-title_${profile_name}_${random_value}.png
    fi
    echo "image_name: ${image_name}"

    # PNG取得
    aws cloudwatch get-metric-widget-image --metric-widget file://result_${profile_name}_${i}.json --output-format "png" --output text --query MetricWidgetImage --profile ${profile_name} | base64 --decode > ${image_name}.png && mv ~/image_dir/${image_name}.png ~/image_dir/${profile_name}
    # json削除
    rm -f result_${profile_name}_${i}.json
    sleep 3
  done
  echo "===================="
  # 対象フォルダをzip化
  zip -r ${Year}${Mon}_${profile_name}.zip ${profile_name}/
  # s3 にアップロード
  aws s3 cp ${Year}${Mon}_${profile_name}.zip s3://${S3_NAME}/${profile_name}/ --profile ${S3_PROFILE}
  # 作成されたファイル削除
  rm -f ~/image_dir/*.zip 
#   rm -f ~/image_dir/${profile_name}/*.png
done

実行してみる

bash ~/get-image-dashboard.sh

image_dir というフォルダ生成され、配下にprofile名毎にフォルダが生成されており、PNGが保存されています。

S3上にもアップロードされています。

Discussion