AWS CLOUD WATCH: CUSTOM METRICS
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.
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!
I had issues with the load_average bash commands. I used load_average=$(uptime | sed 's/.*load average: //' | awk -F\, '{print $2}') and then load_average=$${$load_average%%','} ... is this what you were trying to do?
ReplyDeleteor a little easier:
ReplyDeleteload_average=`awk '{ print $2 }' /proc/loadavg`