AWS Cloud Watch: Custom Metrics

by Andrii Kozhokaru

Hello all!

Today we will talk about custom metrics in CloudWatch of Amazon Web Services. Custom metrics are needed when there is no possibility to check the parameters within the CloudWatch standard metrics. We can do more with custom metrics, for example check connections number between modules, I/O operations on the NFS or Load Average. Basically, I will tell you how to get Load Average metrics shown in your CloudWatch interface.

At the beginning we need:

1. Amazon CloudWatch Command Line Tools.
2. Some bash scripts.

Let's start with the server:

  • Create directory 'aws' in the '/opt' directory.
  • Unzip Command line tools in the '/opt/aws/mon' directory.
  • Put key and certificate - pk-**.pem and cert-**.pem - into the '/opt/aws/keys' directory
  • Create a symbolic link for the proper Java folder at '/usr/java/latest'

So, first we need to understand how to get Load Average. I prefer something like this:

load_average=(uptime | awk -F'load average:' '${ print $2 }' | awk '{ print 2 }') load_average=$${load_average%%','}

In this variable we will save current value of 5 minute Load Average.

Next we need timestamp in the defined format:

timestamp=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)

And at last we need to push the value to the CloudWatch:

mon-put-data --metric-name "LoadAverage" --namespace "CustomMetric" --timestamp $timestamp --value $load_average

So, it looks like we need all to be gathered in the script with loop, system variables and logging:

/opt/aws/cw_scaler.sh:

#!/bin/bash

export AWS_CLOUDWATCH_HOME=/opt/aws/mon
export AWS_CLOUDWATCH_URL=https://monitoring.amazonaws.com
export PATH=AWS_CLOUDWATCH_HOME/bin:PATH
export JAVA_HOME=/usr/java/latest
export TOOLS_HOME=/opt/aws
export EC2_PRIVATE_KEY=$TOOLS_HOME/keys/pk-GWO6MOXPTCZA5EY7**********RSFJ.pem
export EC2_CERT=$TOOLS_HOME/keys/cert-GWO6MOXPTCZA5EY7**********RSFJ.pem


while [ true ]; do
load_average=$(uptime | awk -F'load average:' '$${ print $2 }' | awk '{ print 2 }')
load_average=$${load_average%%','}

timestamp=(date -u +%Y-%m-%dT%H:%M:%S.000Z)

mon-put-data --metric-name "LoadAverage" --namespace "CustomMetric" --timestamp timestamp --value $load_average

echo "$timestamp: Load Average $load_average" >>$TOOLS_HOME/cw_scaler.log

echo "" >>$TOOLS_HOME/cw_scaler.log

sleep 14
done

And also init script to stop|start the actions:

/opt/aws/cw_scaler.sh:

#!/bin/bash

export AWS_CLOUDWATCH_HOME=/opt/aws/mon
export AWS_CLOUDWATCH_URL=https://monitoring.amazonaws.com
export PATH=AWS_CLOUDWATCH_HOME/bin:PATH
export JAVA_HOME=/usr/java/latest
export TOOLS_HOME=/opt/aws
export EC2_PRIVATE_KEY=$TOOLS_HOME/keys/pk-GWO6MOXPTCZA5EY7**********RSFJ.pem
export EC2_CERT=$TOOLS_HOME/keys/cert-GWO6MOXPTCZA5EY7**********RSFJ.pem


while [ true ]; do
load_average=$(uptime | awk -F'load average:' '$${ print $2 }' | awk '{ print 2 }')
load_average=$${load_average%%','}

timestamp=(date -u +%Y-%m-%dT%H:%M:%S.000Z)

mon-put-data --metric-name "LoadAverage" --namespace "CustomMetric" --timestamp timestamp --value $load_average

echo "$timestamp: Load Average $load_average" >>$TOOLS_HOME/cw_scaler.log

echo "" >>$TOOLS_HOME/cw_scaler.log

sleep 14
done

And also init script to stop|start the actions:

/etc/init.d/cw_scaler-init:

#!/bin/bash1
#chkconfig: 2345 55 25
# source function library
. /etc/rc.d/init.d/functions

#Set environement
export TOOLS_HOME=/opt/aws


start()
{
$TOOLS_HOME/cw_scaler.sh&
}

stop()
{
kill $(ps ax | grep '/opt/aws/cw_scaler.sh' | grep -v "grep" | awk '{print $1}')
}

case "$1" in
start)
echo "Starting Cloud Watch scaler."
start
;;
stop)
echo "Stopping Cloud Watch scaler."
stop
;;
*)
echo $"Usage: cw_scaler.sh {start|stop}"
exit 1
;;
esac

And that's all! In 5-10 minutes you will get the following picture in your CloudWatch interface:



Yes gentlemen, it is as simple as I've just described! You can build your own autoscaling system based on this custom metric and do anything you want with it!