Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I would like to get Cloudwatch screenshot automatically since I have many instances.

But when I try to run get-metric-widget-image by aws cli command tool, I always get error.

An error occurred (ValidationError) when calling the GetMetricWidgetImage operation: MetricWidget property 'metricWidget' has a bad JSON content.

Is there anyone who could help me out? Thanks.

I could not find an example from aws doc. No exact example in below link. https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CloudWatch-Metric-Widget-Structure.html

My command is 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,"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" 
like image 345
ingsnow kwan Avatar asked Nov 20 '18 06:11

ingsnow kwan


People also ask

How do I get CloudWatch metrics?

You can collect metrics from servers by installing the CloudWatch agent on the server. You can install the agent on both Amazon EC2 instances and on-premises servers, and on computers running either Linux, Windows Server, or macOS.

What is metric resolution in CloudWatch?

By default, metrics are stored at one-minute resolution in CloudWatch.


2 Answers

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
like image 78
Dejan Peretin Avatar answered Sep 28 '22 10:09

Dejan Peretin


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
like image 41
Nicholas Sushkin Avatar answered Sep 28 '22 09:09

Nicholas Sushkin