{"id":3017,"date":"2015-08-19T11:00:18","date_gmt":"2015-08-19T11:00:18","guid":{"rendered":"http:\/\/blog.cloudthat.com\/?p=3017"},"modified":"2024-06-25T11:13:39","modified_gmt":"2024-06-25T11:13:39","slug":"guide-to-configure-custom-cloudwatch-metric","status":"publish","type":"blog","link":"https:\/\/www.cloudthat.com\/resources\/blog\/implementation-of-custom-cloudwatch-metric-in-amazon-web-services","title":{"rendered":"Implementation of Custom Cloudwatch Metric in Amazon Web Services"},"content":{"rendered":"<p class=\"lang:python decode:true\" title=\"Code for checking invalid metric name and namespace\"><b style=\"font-size: 14px;\">What are metrics?<\/b><\/p>\n<p>Metrics are used to monitor various resources in Amazon Web Services like EBS volumes, EC2 instances and RDS instances. Apart from the pre-defined metrics in AWS, sometimes monitoring is required for additional service parameters. For creating a user defined metric, AWS has introduced custom metrics in CloudWatch.<\/p>\n<p>This feature can be used to store business and application metrics in Amazon CloudWatch. \u00a0Also, a graph plot is generated to give a visual interpretation of the metric. Custom metrics can be setup on almost all services such as Amazon EC2 instances, AWS Billing, Autoscaling, EBS volumes and Relational Database Services. In addition, CloudWatch alarms can be set and automated actions can be configured on the basis of these metrics.<\/p>\n<p>&nbsp;<\/p>\n<p class=\"lang:python decode:true\" title=\"Code for checking invalid metric name and namespace\"><b style=\"font-size: 14px;\">Why use Custom metrics?<\/b><\/p>\n<p>Amazon Web Services provides a wide range of metrics for EBS, EC2 and RDS services. Alarms can be configured on the basis of these metrics and actions like terminating EC2 instances, restarting them or sending messages to SQS can then be taken.<\/p>\n<p>Each of these services have different metrics associated with them and Cloudwatch can measure metrics provided by the hypervisor like disk-read, disk-write and disk usage for EBS and CPU Utilization, CPU credit Usage.<\/p>\n<p>For instance, a user might have to take automated actions based on a particular parameter. This parameter can be the number of active users in a system which can be stored in an RDS instance. A script can be used to measure this value and if the number of users is zero for a particular time period, an alarm needs to be triggered and the EC2 instance needs to be terminated.<\/p>\n<p>&nbsp;<\/p>\n<p class=\"lang:python decode:true\" title=\"Code for checking invalid metric name and namespace\"><b style=\"font-size: 14px;\">Use Case:<\/b><\/p>\n<p>For instance, a user might have to take automated actions based on a particular parameter. This parameter can be the number of active users in a system which can be stored in an RDS instance. A script can be used to measure this value and if the number of users is zero for a particular time period, an alarm needs to be triggered and the EC2 instance needs to be terminated.<\/p>\n<p>Now let us see how we can configure a custom metric based on the above use case:<\/p>\n<p>&nbsp;<\/p>\n<p><b>Prerequisites:<\/b><\/p>\n<ul>\n<li>python 2.7.x<\/li>\n<\/ul>\n<ul>\n<li>boto 2.36.0<\/li>\n<\/ul>\n<p><strong><span style=\"font-weight: 400;\">In the following steps we will configure a custom metric to monitor the active sessions of a particular user using an RDS instance and create an alarm for this custom metric to terminate EC2 instance when it reaches the threshold of zero.<\/span><\/strong><\/p>\n<p><b>Creating a custom metric<\/b><\/p>\n<p>The following code snippet can either be run on python interactive console or the whole code can be copied and run using it as a python script.<\/p>\n<pre class=\"theme:sublime-text lang:python decode:true\">from boto.ec2.cloudwatch import connect_to_region\r\n\r\nimport MySQLdb\r\n\r\nimport boto.ec2.cloudwatch\r\n\r\ndb=MySQLdb.connect(\"ravit.rdshostname.ap-northeast-1.rds.amazonaws.com\",\"username\",\"password\",\"databasename\")\r\n\r\ncursor=db.cursor()\r\n\r\nn=cursor.execute(\"select * from GetActiveSessions\")\r\n\r\nn1=cursor.fetchone()\r\n\r\ns=str(n1)\r\n\r\ntable=string.maketrans( '', '', )\r\n\r\nnumber=s.translate(table,\"(){}&lt;&gt;,L\")\r\n\r\nnumbers=int(number)\r\n\r\nreg='ap-northeast-1'\r\n\r\nconn_cw=boto.ec2.cloudwatch.connect_to_region(reg,aws_access_key_id=\u2019your_access_key\u2019,aws_secret_access_key=\u2019your_secret_key\u2019)\t\t\r\n\r\nconn_cw.put_metric_data(namespace='my_namespace',name='my_metric',value=numbers,dimensions={'InstanceId':'i-a1b2c3d4'})\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">The following code gets the active number of users in RDS running MySQL and updates the custom metric based on that value. This script can be run as a cron job to get dynamic values where for every one minute the value of the custom metric is updated.<\/span><\/p>\n<table style=\"height: 280px;\" border=\"1\" width=\"707\">\n<tbody>\n<tr>\n<td><b>Parameter<\/b><\/td>\n<td><b>Input parameter type<\/b><\/td>\n<td><b>Description<\/b><\/td>\n<\/tr>\n<tr>\n<td>namespace<\/td>\n<td>string<\/td>\n<td>The namespace of the alarm to tag.<\/td>\n<\/tr>\n<tr>\n<td>name<\/td>\n<td>list or string<\/td>\n<td>The list of names to add the alarms or a string name to add a single alarm name.<\/td>\n<\/tr>\n<tr>\n<td>value<\/td>\n<td>int, float or list<\/td>\n<td>The list or a single int value to add to the alarm.<\/td>\n<\/tr>\n<tr>\n<td>dimensions<\/td>\n<td>dictionary<\/td>\n<td>The name-value pairs to associate with the metric.The dimensions can either be InstanceId key-value pairs or InstanceName key-value-pair.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p><b>Note:<\/b>\u00a0For values like \u00a0CPUUtilization, AWS\/EC2 cannot be used in the namespace and name field because they are pre-defined values and cannot be overridden. These values can be accessed by using the function:<\/p>\n<pre class=\"theme:sublime-text lang:python decode:true\" title=\"Code snippet to check invalid name and namespaces for custom metric\">metrics=boto.ec2.cloudwatch.CloudWatchConnection(aws_access_key_id=\u2019your_access_key\u2019,aws_secret_access_key=\u2019your_secret_key\u2019).list_metrics()\r\n\r\nfor metric in metrics:\r\n\tprint metric.name +\u201d\\t\u201d+ metric.namespace\r\n<\/pre>\n<p>The above code prints a list of metric name and metric namespace values which cannot be used in the custom metric function.<\/p>\n<p><b>How to check whether the custom metric was created:<\/b><br \/>\nStep 1. Navigate to CloudWatch in the \u00a0AWS Management Console. A new dropdown menu called &#8216;<strong>custom metrics&#8217;<\/strong> appears. Click on it.<\/p>\n<p><a href=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/custom_metrics_1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-3023 \" src=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/custom_metrics_1.png\" alt=\"custom_metrics_1\" width=\"901\" height=\"587\" \/><\/a><\/p>\n<p>Step 2. Click on the drop down menu, the newly created metric\u2019s namespace \u2018<strong>my_namespace<\/strong>\u2019 is displayed, click on it.<\/p>\n<p><a href=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/custom_metrics_3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3025\" src=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/custom_metrics_3.png\" alt=\"custom_metrics_3\" width=\"958\" height=\"642\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Step 3. The newly created metric \u2018<strong>my_metric<\/strong>\u2019 for the instance \u2018<strong>i-a1b2c3d4<\/strong>\u2019 can be viewed.<\/p>\n<p><a href=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/custom_metrics_3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-3025\" src=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/custom_metrics_3.png\" alt=\"custom_metrics_3\" width=\"901\" height=\"604\" \/><\/a><\/p>\n<p><strong>Creating a CloudWatch alarm for the custom metric<\/strong><\/p>\n<p>Now that the custom metric is created, we need to create an alarm for it. This alarm can be created \u00a0using the AWS Management console or can be done using the following script:<\/p>\n<pre class=\"theme:sublime-text lang:python decode:true\">from boto.ec2.cloudwatch import connect_to_region\r\n\r\nimport boto.ec2.cloudwatch\r\n\r\nmetric=cw.list_metrics(dimensions={'InstanceId':\u2019i-a1b2c3d4\u2019},metric_name='my_metric')[0]\r\n\r\nmetric.create_alarm(name='my_alarm', comparison='&lt;=', threshold=0, period=300,evaluation_periods=1, statistic='Average', alarm_actions='arn:aws:automate:ap-northeast-1:ec2:terminate')\r\n<\/pre>\n<p>The following code snippet creates an alarm called \u2018<strong>my_alarm<\/strong>\u2019 for the custom metric. Whenever the value of the custom metric is zero for 5 minutes time period the alarm terminates the EC2 instance.<\/p>\n<p>&nbsp;<\/p>\n<table style=\"height: 281px;\" border=\"1\" width=\"920\">\n<tbody>\n<tr>\n<td><b>Parameter<\/b><\/td>\n<td><b>Input parameter type<\/b><\/td>\n<td><b>Description<\/b><\/td>\n<\/tr>\n<tr>\n<td>name<\/td>\n<td>list or string<\/td>\n<td>The list of names to add the alarms or a string name to add a single alarm name.<\/td>\n<\/tr>\n<tr>\n<td>comparison<\/td>\n<td>operators<\/td>\n<td>The operator to check the custom metric values<\/td>\n<\/tr>\n<tr>\n<td>threshold<\/td>\n<td>int or float<\/td>\n<td>The value for which the alarm should take action<\/td>\n<\/tr>\n<tr>\n<td>period<\/td>\n<td>int<\/td>\n<td>The time period for which the alarm should take action<\/td>\n<\/tr>\n<tr>\n<td>evaluation_period<\/td>\n<td>int<\/td>\n<td>The number of times the value has passed the threshold in order for the alarm to activate<\/td>\n<\/tr>\n<tr>\n<td>statistic<\/td>\n<td>string<\/td>\n<td>The statistical value for the metric<\/td>\n<\/tr>\n<tr>\n<td>alarm_actions<\/td>\n<td>string<\/td>\n<td>The arn of the action to be taken once the alarm is active.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note:\u00a0The put metric data must actively supply the metric value in order for the alarm to be in ok state or else it will be in insufficient state.<\/p>\n<p>&nbsp;<\/p>\n<p>Perform the following steps to view the alarm using the AWS Management console .<\/p>\n<p>Go to AWS console and open CloudWatch and select &#8216;<strong>alarms&#8217;<\/strong>.<\/p>\n<p><a href=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/alarm.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-3026\" src=\"https:\/\/content.cloudthat.com\/resources\/wp-content\/uploads\/2022\/11\/alarm.png\" alt=\"alarm\" width=\"901\" height=\"609\" \/><\/a><\/p>\n<p>Using the above steps, we have created a custom metric called \u2018my_metric\u2019, gave it a static value of 10 and associated it with an EC2 instance. We also created a CloudWatch alarm called \u2018my_alarm\u2019 \u00a0configured the alarm \u00a0to terminate the instance if the value of metric is zero for 5 minutes. The alarm will go in insufficient state if the custom metric has a static value. The metric created should have dynamic input at a fixed time intervals so that the alarm is in \u2018ok\u2019 state. This can be achieved by using a cron job to supply dynamic values to CloudWatch.<\/p>\n<p><b>Pricing<\/b><\/p>\n<ul>\n<li>$0.10 per \u00a0EC2-instance CloudWatch Alarm created<\/li>\n<li>$3.50 per EC2-instance per month CloudWatch Alarm created if detailed monitoring is enabled<\/li>\n<li>$0.50 per metric per instance for custom CloudWatch metric.<\/li>\n<\/ul>\n<p><b>Limitations:<\/b><\/p>\n<ul>\n<li>can only be created\u00a0for numeric values.<\/li>\n<li>Cannot be created\u00a0through AWS Management Console.<\/li>\n<li>Does not work for static values.<\/li>\n<li>Custom metric data needs to be updated timely or else the alarm will be in insufficient<\/li>\n<\/ul>\n<p>For further queries regarding creation of custom metrics, please feel free to comment below and I will be happy to answer.<\/p>\n","protected":false},"author":219,"featured_media":0,"parent":0,"comment_status":"open","ping_status":"open","template":"","blog_category":[3606,3665],"user_email":"prarthitm@cloudthat.com","published_by":"324","primary-authors":"","secondary-authors":"","acf":[],"_links":{"self":[{"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/blog\/3017"}],"collection":[{"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/users\/219"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/comments?post=3017"}],"version-history":[{"count":2,"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/blog\/3017\/revisions"}],"predecessor-version":[{"id":45719,"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/blog\/3017\/revisions\/45719"}],"wp:attachment":[{"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/media?parent=3017"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.cloudthat.com\/resources\/wp-json\/wp\/v2\/blog_category?post=3017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}