How to use aws cloudwatch get-metric-widget-image?

The best way to get the correct json for your request is to use CloudWatch Console to construct the graph, then click on the Source tab, select Image API view and click Copy Source to copy the json generated there. You also need to wrap the json in single quotes, like this:

aws cloudwatch get-metric-widget-image --metric-widget \
'{
    "width": 600,
    "height": 395,
    "metrics": [
        [ "AWS/EC2", "CPUUtilization", "InstanceId", "i-01234567890123456", { "stat": "Average" } ]
    ],
    "period": 300,
    "stacked": false,
    "yAxis": {
        "left": {
            "min": 0.1,
            "max": 1
        },
        "right": {
            "min": 0
        }
    },
    "title": "CPU",
    "annotations": {
        "horizontal": [
            {
                "color": "#ff6961",
                "label": "Troublethresholdstart",
                "fill": "above",
                "value": 0.5
            }
        ],
        "vertical": [
            {
                "visible": true,
                "color": "#9467bd",
                "label": "Bugfixdeployed",
                "value": "2018-11-19T07:25:26Z",
                "fill": "after"
            }
        ]
    },
    "view": "timeSeries"
}'

Response to this will be a base64 encoded image, like this:

{
    "MetricWidgetImage": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAGLEAYA..."
}

If you need the raw png image, you'll need to decode the response by doing something like this:

aws cloudwatch get-metric-widget-image --metric-widget 'JSON_GOES_HERE' | grep MetricWidgetImage | awk '{split($0,a,"\""); print a[4]}' | base64 --decode > graph.png

Here's a different answer. Within https://github.com/kcrossen/CloudWatch_Remote_Monitor/blob/master/Source_Code/ there is a Python script that will digest your dashboard source code mentioned by Tartaglia above and generate the proper json parameters for GetMetricWidgetImage. There's also a Kivy script to display the PNG images returned.


Here is a script I use to download images for the same metric for each day. The script shows how to invoke aws cloudwatch get-metric-widget-image with variable arguments and to convert output to a png file.

function getDbDailyMetricImage
{
    local date=$1
    local dbId=$2
    local metric=${3:-'CPUUtilization'}
    local metricMin=$4
    local metricMax=$5

    local dateF=$(date --date="$date" +%F)
    local start="${dateF}T00:00:00.000Z"
    local end="${dateF}T23:59:59.999Z"

    echo "Downloading image for $dbId $metric [$metricMin .. $metricMax]" \
         "and Time [$start .. $end]"
    aws --region us-east-1 cloudwatch get-metric-widget-image --metric-widget \
        '{
          "metrics": [
              [ "AWS/RDS", "'$metric'", "DBInstanceIdentifier", "'$dbId'", 
                { "period": 300, "yAxis": "left" } ]
          ],
          "yAxis": {
             "left": {
                 "min": '$metricMin',
                 "max": '$metricMax'
             }
          },
          "title": "'"$dateF $metric of $dbId vs Time UTC"'",
          "legend": {
             "position": "hidden"
          },
          "view": "timeSeries",
          "stacked": true,
          "period": 300,
          "width": 1200,
          "height": 800,
          "start": "'$start'",
          "end": "'$end'"
        }' \
        --output-format png --output text | base64 --decode > $metric-$dbId-$dateF.png
}

for daysAgo in {0..30}
do
    getDbDailyMetricImage $(date --date="$daysAgo days ago" +%F) mydb1 CPUUtilization 0 100
    getDbDailyMetricImage $(date --date="$daysAgo days ago" +%F) mydb1 ReadIOPS 0 10000
done

another useful analytic tool I use it to combine all or some of the graphs into one using ImageMagick convert -compose Multiply. For example,

convert ReadIOPS-mydb1-2019-0*.png -compose Multiply -layers flatten ReadIOPS-mydb1-2019-composite.png

JSONLint says that you've got one extra } at the end of your JSON. Also, try wrapping the whole JSON block with single quotes ' for easier differentiating and no need to escape the double quotes in the JSON string.

This should work for you:

aws cloudwatch get-metric-widget-image --metric-widget '{ "width":600,"height":395,"metrics":[["AWS/EC2","CPUUtilization","InstanceId","i-01234567890123456",{"stat":"Average"}]],"period":300,"start":"-P30D","end":"PT0H","stacked":false,"yAxis":{"left":{"min":0.1,"max":1},"right":{"min":0}},"title":"CPU","annotations":{"horizontal":[{"color":"#ff6961","label":"Troublethresholdstart","fill":"above","value":0.5}], "vertical":[{"visible":true, "color":"#9467bd","label":"Bugfixdeployed","value":"2018-11-19T07:25:26Z","fill":"after"}]}}' --output-format "png"