web/Zend/Service/Amazon/Ec2/CloudWatch.php
changeset 0 4eba9c11703f
equal deleted inserted replaced
-1:000000000000 0:4eba9c11703f
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Service_Amazon
       
    17  * @subpackage Ec2
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: CloudWatch.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    21  */
       
    22 
       
    23 /**
       
    24  * @see Zend_Service_Amazon_Ec2_Abstract
       
    25  */
       
    26 require_once 'Zend/Service/Amazon/Ec2/Abstract.php';
       
    27 
       
    28 /**
       
    29  * An Amazon EC2 interface that allows yout to run, terminate, reboot and describe Amazon
       
    30  * Ec2 Instances.
       
    31  *
       
    32  * @category   Zend
       
    33  * @package    Zend_Service_Amazon
       
    34  * @subpackage Ec2
       
    35  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    36  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    37  */
       
    38 class Zend_Service_Amazon_Ec2_CloudWatch extends Zend_Service_Amazon_Ec2_Abstract
       
    39 {
       
    40     /**
       
    41      * The HTTP query server
       
    42      */
       
    43     protected $_ec2Endpoint = 'monitoring.amazonaws.com';
       
    44 
       
    45     /**
       
    46      * The API version to use
       
    47      */
       
    48     protected $_ec2ApiVersion = '2009-05-15';
       
    49 
       
    50     /**
       
    51      * XML Namespace for the CloudWatch Stuff
       
    52      */
       
    53     protected $_xmlNamespace = 'http://monitoring.amazonaws.com/doc/2009-05-15/';
       
    54 
       
    55     /**
       
    56      * The following metrics are available from each EC2 instance.
       
    57      *
       
    58      * CPUUtilization: The percentage of allocated EC2 compute units that are
       
    59      *  currently in use on the instance. This metric identifies the processing
       
    60      *  power required to run an application upon a selected instance.
       
    61      *
       
    62      * NetworkIn: The number of bytes received on all network interfaces by
       
    63      *  the instance. This metric identifies the volume of incoming network
       
    64      *  traffic to an application on a single instance.
       
    65      *
       
    66      * NetworkOut: The number of bytes sent out on all network interfaces
       
    67      *  by the instance. This metric identifies the volume of outgoing network
       
    68      *  traffic to an application on a single instance.
       
    69      *
       
    70      * DiskWriteOps: Completed write operations to all hard disks available to
       
    71      *  the instance. This metric identifies the rate at which an application
       
    72      *  writes to a hard disk. This can be used to determine the speed in which
       
    73      *  an application saves data to a hard disk.
       
    74      *
       
    75      * DiskReadBytes: Bytes read from all disks available to the instance. This
       
    76      *  metric is used to determine the volume of the data the application reads
       
    77      *  from the hard disk of the instance. This can be used to determine the
       
    78      *  speed of the application for the customer.
       
    79      *
       
    80      * DiskReadOps: Completed read operations from all disks available to the
       
    81      *  instances. This metric identifies the rate at which an application reads
       
    82      *  a disk. This can be used to determine the speed in which an application
       
    83      *  reads data from a hard disk.
       
    84      *
       
    85      * DiskWriteBytes: Bytes written to all disks available to the instance. This
       
    86      *  metric is used to determine the volume of the data the application writes
       
    87      *  onto the hard disk of the instance. This can be used to determine the speed
       
    88      *  of the application for the customer.
       
    89      *
       
    90      * Latency: Time taken between a request and the corresponding response as seen
       
    91      *  by the load balancer.
       
    92      *
       
    93      * RequestCount: The number of requests processed by the LoadBalancer.
       
    94      *
       
    95      * HealthyHostCount: The number of healthy instances. Both Load Balancing dimensions,
       
    96      *  LoadBalancerName and AvailabilityZone, should be specified when retreiving
       
    97      *  HealthyHostCount.
       
    98      *
       
    99      * UnHealthyHostCount: The number of unhealthy instances. Both Load Balancing dimensions,
       
   100      *  LoadBalancerName and AvailabilityZone, should be specified when retreiving
       
   101      *  UnHealthyHostCount.
       
   102      *
       
   103      * Amazon CloudWatch data for a new EC2 instance becomes available typically
       
   104      * within one minute of the end of the first aggregation period for the new
       
   105      * instance. You can use the currently available dimensions for EC2 instances
       
   106      * along with these metrics in order to refine the slice of data you want returned,
       
   107      * such as metric CPUUtilization and dimension ImageId to get all CPUUtilization
       
   108      * data for instances using the specified AMI.
       
   109      *
       
   110      * @var array
       
   111      */
       
   112     protected $_validMetrics = array('CPUUtilization', 'NetworkIn', 'NetworkOut',
       
   113                                     'DiskWriteOps', 'DiskReadBytes', 'DiskReadOps',
       
   114                                     'DiskWriteBytes', 'Latency', 'RequestCount',
       
   115                                     'HealthyHostCount', 'UnHealthyHostCount');
       
   116 
       
   117     /**
       
   118      * Amazon CloudWatch not only aggregates the raw data coming in, it also computes
       
   119      * several statistics on the data. The following table lists the statistics that you can request:
       
   120      *
       
   121      * Minimum: The lowest value observed during the specified period. This can be used to
       
   122      *  determine low volumes of activity for your application.
       
   123      *
       
   124      * Maximum: The highest value observed during the specified period. You can use this to
       
   125      *  determine high volumes of activity for your application.
       
   126      *
       
   127      * Sum: The sum of all values received (if appropriate, for example a rate would not be
       
   128      *  summed, but a number of items would be). This statistic is useful for determining
       
   129      *  the total volume of a metric.
       
   130      *
       
   131      * Average: The Average of all values received during the specified period. By comparing
       
   132      *  this statistic with the minimum and maximum statistics, you can determine the full
       
   133      *  scope of a metric and how close the average use is to the minimum and the maximum.
       
   134      *  This will allow you to increase or decrease your resources as needed.
       
   135      *
       
   136      * Samples: The count (number) of measures used. This statistic is always returned to
       
   137      *  show the user the size of the dataset collected. This will allow the user to properly
       
   138      *  weight the data.
       
   139      *
       
   140      * Statistics are computed within a period you specify, such as all CPUUtilization within a
       
   141      * five minute period. At a minimum, all data is aggregated into one minute intervals. This
       
   142      * is the minimum resolution of the data. It is this data that can be aggregated into larger
       
   143      * periods of time that you request.
       
   144      *
       
   145      * Aggregate data is generally available from the service within one minute from the end of the
       
   146      * aggregation period. Delays in data propagation might cause late or partially late data in
       
   147      * some cases. If your data is delayed, you should check the service’s Health Dashboard for
       
   148      * any current operational issues with either Amazon CloudWatch or the services collecting
       
   149      * the data, such as EC2 or Elastic Load Balancing.
       
   150      *
       
   151      * @var array
       
   152      */
       
   153     protected $_validStatistics = array('Average', 'Maximum', 'Minimum', 'Samples', 'Sum');
       
   154 
       
   155     /**
       
   156      * Valid Dimention Keys for getMetricStatistics
       
   157      *
       
   158      * ImageId: This dimension filters the data you request for all instances running
       
   159      *  this EC2 Amazon Machine Image (AMI).
       
   160      *
       
   161      * AvailabilityZone: This dimension filters the data you request for all instances
       
   162      *  running in that EC2 Availability Zone.
       
   163      *
       
   164      * AutoScalingGroupName: This dimension filters the data you request for all instances
       
   165      *  in a specified capacity group. An AutoScalingGroup is a collection of instances
       
   166      *  defined by customers of the Auto Scaling service. This dimension is only available
       
   167      *  for EC2 metrics when the instances are in such an AutoScalingGroup.
       
   168      *
       
   169      * InstanceId: This dimension filters the data you request for only the identified
       
   170      *  instance. This allows a user to pinpoint an exact instance from which to monitor data.
       
   171      *
       
   172      * InstanceType: This dimension filters the data you request for all instances running
       
   173      *  with this specified instance type. This allows a user to catagorize his data by the
       
   174      *  type of instance running. For example, a user might compare data from an m1.small instance
       
   175      *  and an m1.large instance to determine which has the better business value for his application.
       
   176      *
       
   177      * LoadBalancerName: This dimension filters the data you request for the specified LoadBalancer
       
   178      *  name. A LoadBalancer is represented by a DNS name and provides the single destination to
       
   179      *  which all requests intended for your application should be directed. This metric allows
       
   180      *  you to examine data from all instances connected to a single LoadBalancer.
       
   181      *
       
   182      * @var array
       
   183      */
       
   184     protected $_validDimensionsKeys = array('ImageId', 'AvailabilityZone', 'AutoScalingGroupName',
       
   185                                             'InstanceId', 'InstanceType', 'LoadBalancerName');
       
   186 
       
   187     /**
       
   188      * Returns data for one or more statistics of given a metric
       
   189      *
       
   190      * Note:
       
   191      * The maximum number of datapoints that the Amazon CloudWatch service will
       
   192      * return in a single GetMetricStatistics request is 1,440. If a request is
       
   193      * made that would generate more datapoints than this amount, Amazon CloudWatch
       
   194      * will return an error. You can alter your request by narrowing the time range
       
   195      * (StartTime, EndTime) or increasing the Period in your single request. You may
       
   196      * also get all of the data at the granularity you originally asked for by making
       
   197      * multiple requests with adjacent time ranges.
       
   198      *
       
   199      * @param array $options            The options you want to get statistics for:
       
   200      *                                  ** Required **
       
   201      *                                  MeasureName: The measure name that corresponds to
       
   202      *                                      the measure for the gathered metric. Valid EC2 Values are
       
   203      *                                      CPUUtilization, NetworkIn, NetworkOut, DiskWriteOps
       
   204      *                                      DiskReadBytes, DiskReadOps, DiskWriteBytes. Valid Elastic
       
   205      *                                      Load Balancing Metrics are Latency, RequestCount, HealthyHostCount
       
   206      *                                      UnHealthyHostCount
       
   207      *                                  Statistics: The statistics to be returned for the given metric. Valid
       
   208      *                                      values are Average, Maximum, Minimum, Samples, Sum.  You can specify
       
   209      *                                      this as a string or as an array of values.  If you don't specify one
       
   210      *                                      it will default to Average instead of failing out.  If you specify an incorrect
       
   211      *                                      option it will just skip it.
       
   212      *                                  ** Optional **
       
   213      *                                  Dimensions: Amazon CloudWatch allows you to specify one Dimension to further filter
       
   214      *                                      metric data on. If you don't specify a dimension, the service returns the aggregate
       
   215      *                                      of all the measures with the given measure name and time range.
       
   216      *                                  Unit: The standard unit of Measurement for a given Measure. Valid Values: Seconds,
       
   217      *                                      Percent, Bytes, Bits, Count, Bytes/Second, Bits/Second, Count/Second, and None
       
   218      *                                      Constraints: When using count/second as the unit, you should use Sum as the statistic
       
   219      *                                      instead of Average. Otherwise, the sample returns as equal to the number of requests
       
   220      *                                      instead of the number of 60-second intervals. This will cause the Average to
       
   221      *                                      always equals one when the unit is count/second.
       
   222      *                                  StartTime: The timestamp of the first datapoint to return, inclusive. For example,
       
   223      *                                      2008-02-26T19:00:00+00:00. We round your value down to the nearest minute.
       
   224      *                                      You can set your start time for more than two weeks in the past. However,
       
   225      *                                      you will only get data for the past two weeks. (in ISO 8601 format)
       
   226      *                                      Constraints: Must be before EndTime
       
   227      *                                  EndTime: The timestamp to use for determining the last datapoint to return. This is
       
   228      *                                      the last datapoint to fetch, exclusive. For example, 2008-02-26T20:00:00+00:00.
       
   229      *                                      (in ISO 8601 format)
       
   230      */
       
   231     public function getMetricStatistics(array $options)
       
   232     {
       
   233         $_usedStatistics = array();
       
   234 
       
   235         $params = array();
       
   236         $params['Action'] = 'GetMetricStatistics';
       
   237 
       
   238         if (!isset($options['Period'])) {
       
   239             $options['Period'] = 60;
       
   240         }
       
   241         if (!isset($options['Namespace'])) {
       
   242             $options['Namespace'] = 'AWS/EC2';
       
   243         }
       
   244 
       
   245         if (!isset($options['MeasureName']) || !in_array($options['MeasureName'], $this->_validMetrics, true)) {
       
   246             throw new Zend_Service_Amazon_Ec2_Exception('Invalid Metric Type: ' . $options['MeasureName']);
       
   247         }
       
   248 
       
   249         if(!isset($options['Statistics'])) {
       
   250             $options['Statistics'][] = 'Average';
       
   251         } elseif(!is_array($options['Statistics'])) {
       
   252             $options['Statistics'][] = $options['Statistics'];
       
   253         }
       
   254 
       
   255         foreach($options['Statistics'] as $k=>$s) {
       
   256             if(!in_array($s, $this->_validStatistics, true)) continue;
       
   257             $options['Statistics.member.' . ($k+1)] = $s;
       
   258             $_usedStatistics[] = $s;
       
   259         }
       
   260         unset($options['Statistics']);
       
   261 
       
   262         if(isset($options['StartTime'])) {
       
   263             if(!is_numeric($options['StartTime'])) $options['StartTime'] = strtotime($options['StartTime']);
       
   264             $options['StartTime'] = gmdate('c', $options['StartTime']);
       
   265         } else {
       
   266             $options['StartTime'] = gmdate('c', strtotime('-1 hour'));
       
   267         }
       
   268 
       
   269         if(isset($options['EndTime'])) {
       
   270             if(!is_numeric($options['EndTime'])) $options['EndTime'] = strtotime($options['EndTime']);
       
   271             $options['EndTime'] = gmdate('c', $options['EndTime']);
       
   272         } else {
       
   273             $options['EndTime'] = gmdate('c');
       
   274         }
       
   275 
       
   276         if(isset($options['Dimensions'])) {
       
   277             $x = 1;
       
   278             foreach($options['Dimensions'] as $dimKey=>$dimVal) {
       
   279                 if(!in_array($dimKey, $this->_validDimensionsKeys, true)) continue;
       
   280                 $options['Dimensions.member.' . $x . '.Name'] = $dimKey;
       
   281                 $options['Dimensions.member.' . $x . '.Value'] = $dimVal;
       
   282                 $x++;
       
   283             }
       
   284             
       
   285             unset($options['Dimensions']);
       
   286         }
       
   287 
       
   288         $params = array_merge($params, $options);
       
   289 
       
   290         $response = $this->sendRequest($params);
       
   291         $response->setNamespace($this->_xmlNamespace);
       
   292 
       
   293         $xpath = $response->getXPath();
       
   294         $nodes = $xpath->query('//ec2:GetMetricStatisticsResult/ec2:Datapoints/ec2:member');
       
   295 
       
   296         $return = array();
       
   297         $return['label'] = $xpath->evaluate('string(//ec2:GetMetricStatisticsResult/ec2:Label/text())');
       
   298         foreach ( $nodes as $node ) {
       
   299             $item = array();
       
   300 
       
   301             $item['Timestamp'] = $xpath->evaluate('string(ec2:Timestamp/text())', $node);
       
   302             $item['Unit'] = $xpath->evaluate('string(ec2:Unit/text())', $node);
       
   303             $item['Samples'] = $xpath->evaluate('string(ec2:Samples/text())', $node);
       
   304             foreach($_usedStatistics as $us) {
       
   305                 $item[$us] = $xpath->evaluate('string(ec2:' . $us . '/text())', $node);
       
   306             }
       
   307 
       
   308             $return['datapoints'][] = $item;
       
   309             unset($item, $node);
       
   310         }
       
   311 
       
   312         return $return;
       
   313 
       
   314     }
       
   315 
       
   316     /**
       
   317      * Return the Metrics that are aviable for your current monitored instances
       
   318      *
       
   319      * @param string $nextToken     The NextToken parameter is an optional parameter
       
   320      *                                 that allows you to retrieve the next set of results
       
   321      *                                 for your ListMetrics query.
       
   322      * @return array
       
   323      */
       
   324     public function listMetrics($nextToken = null)
       
   325     {
       
   326         $params = array();
       
   327         $params['Action'] = 'ListMetrics';
       
   328         if (!empty($nextToken)) {
       
   329             $params['NextToken'] = $nextToken;
       
   330         }
       
   331 
       
   332         $response = $this->sendRequest($params);
       
   333         $response->setNamespace($this->_xmlNamespace);
       
   334 
       
   335         $xpath = $response->getXPath();
       
   336         $nodes = $xpath->query('//ec2:ListMetricsResult/ec2:Metrics/ec2:member');
       
   337 
       
   338         $return = array();
       
   339         foreach ( $nodes as $node ) {
       
   340             $item = array();
       
   341 
       
   342             $item['MeasureName'] = $xpath->evaluate('string(ec2:MeasureName/text())', $node);
       
   343             $item['Namespace'] = $xpath->evaluate('string(ec2:Namespace/text())', $node);
       
   344             $item['Deminsions']['name'] = $xpath->evaluate('string(ec2:Dimensions/ec2:member/ec2:Name/text())', $node);
       
   345             $item['Deminsions']['value'] = $xpath->evaluate('string(ec2:Dimensions/ec2:member/ec2:Value/text())', $node);
       
   346 
       
   347             if (empty($item['Deminsions']['name'])) {
       
   348                 $item['Deminsions'] = array();
       
   349             }
       
   350 
       
   351             $return[] = $item;
       
   352             unset($item, $node);
       
   353         }
       
   354 
       
   355         return $return;
       
   356     }
       
   357 }