I thought it would be fun to show the new CloudWatch User-Defined metrics in action so I spent a couple of hours cooking up a little example. I launched an EC2 Micro instance, installed PHP, Emacs, the MySQL development package, and the AWS SDK for PHP.
The first step is to include the master file for the SDK:
Access objects are created for RDS and CloudWatch:
$RDS = new AmazonRDS();
$CW = new AmazonCloudWatch();
The RDS object is then used to fetch a list of DB Instances:
$db_instances = $RDS->describe_db_instances();
A simple for loop is used to process each DB Instance in turn. Within the loop, we focus on the database instances that are available (as opposed to other states, such as modifying) and that are running MySQL:
{
if ($db_instance->DBInstanceStatus == 'available' &&
$db_instance->Engine == 'mysql')
{
}
)
The rest of the code is within the if statement. I've broken it out for clarity. The DB Instance Id, Endpoint, and master user name are extracted:
$Endpoint = $db_instance->Endpoint -> Address . ':' . $db_instance->Endpoint->Port;
$MasterUsername = $db_instance->MasterUsername;
This information is used to establish a connection to the MySQL server running on the DB Instance and to run the "show status" command on the instance. RDS knows (but refuses to divulge for security reasons) the password for the master user, so I've hard-coded it for this example.
{
exit("Could not connect to MySQL database ${DBInstanceId} at ${Endpoint}\n");
}
if (!($res = mysql_query('show status')))
{
exit("Could not query database\n");
}
The show status command returns multiple rows of data. The next step is to convert all of this data into a single associative array and to close the connection to the MySQL server.
while ($row = mysql_fetch_assoc($res))
{
$status[$row['Variable_name']] = $row['Value'];
}
mysql_close ($db);
Now it is time to extract the information to be stored in CloudWatch, and to display it for debugging:
$Uptime = $status['Uptime'];
$TableLocksImmediate = $status['Table_locks_immediate'];
$ThreadsCreated = $status['Threads_created'];
print(" Uptime: ${Uptime}\n");
print(" Locks immediate: ${TableLocksImmediate}\n");
print(" Threads created: ${ThreadsCreated}\n");
Now we get to the heart of the matter, actually storing the information into CloudWatch. It took me a couple of tries to get the call to work, so feel free to start from where I left off! Here's all the code that's needed to store three separate user-defined metrics in CloudWatch:
$res1 = $CW->put_metric_data('Sys/RDS' ,
array(array('MetricName' => 'Uptime' ,
'Dimensions' => array(array('Name' => 'DBInstanceIdentifier',
'Value' => $DBInstanceId)),
'Value' => $Uptime,
'Unit' => 'Seconds')));
$res2 = $CW->put_metric_data('Sys/RDS' ,
array(array('MetricName' => 'LocksImmediate' ,
'Dimensions' => array(array('Name' => 'DBInstanceIdentifier',
'Value' => $DBInstanceId)),
'Value' => $TableLocksImmediate,
'Unit' => 'Count')));
$res3 = $CW->put_metric_data ('Sys/RDS' ,
array(array('MetricName' => 'ThreadsCreated' ,
'Dimensions' => array(array('Name' => 'DBInstanceIdentifier',
'Value' => $DBInstanceId)),
'Value' => $ThreadsCreated,
'Unit' => 'Count')));
Remember that you can store any sort of metrics you want, for AWS resources or for your own application-level resources.
The calls to put_metric_data will return errors if the parameters aren't correct, so error checking is (as always) a good idea:
{
print(" Metrics stored!\n\n");
}
else
{
print(" Metric not stored!\n\n");
}
}
Once I had everything running I set up a crontab entry to invoke the code above every 5 minutes:
That's all the code and setup needed to locate a set of RDS DB Instances, connect to each of them in turn, get some statistics, and store the statistics in CloudWatch. Pretty simple, don't you think?
-- Jeff;


Thats pretty interesting.
Is it also possible with this feature to log "operation x" per time in our app?
So whenever x happens within our app, we tell cloudwatch an are able to monitor let's say "new xyz objects in our app per time"?
This way we wouldn't even need a cron since we just log whenever the app actually does something for the user?
what's the runtime penalty when doing something like that? what about pricing?
Posted by: Joshua | May 11, 2011 at 10:04 AM
Good PHP cooking...
Is there any code sample on how to put my own custom metrics (say view counters for each page in my site) into cloudwatch using AWS SDK for Java..
The samples provided with the AWS SDK does not have anything for Cloudwatch..
Any sample for publishing custom metrics would be helpful to start with..
Thanks
Posted by: NK | November 02, 2011 at 07:13 PM
how to code it java
Posted by: artkala | April 27, 2012 at 03:43 AM