| Index: boto/ec2/cloudwatch/__init__.py
|
| diff --git a/boto/ec2/cloudwatch/__init__.py b/boto/ec2/cloudwatch/__init__.py
|
| index a02baa366cd34d36766a7eb5b2928a6121d18fd5..1c61736eb4346bb45635843c573ac21e75b40ded 100644
|
| --- a/boto/ec2/cloudwatch/__init__.py
|
| +++ b/boto/ec2/cloudwatch/__init__.py
|
| @@ -1,4 +1,4 @@
|
| -# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
|
| +# Copyright (c) 2006-2011 Mitch Garnaat http://garnaat.org/
|
| #
|
| # Permission is hereby granted, free of charge, to any person obtaining a
|
| # copy of this software and associated documentation files (the
|
| @@ -140,6 +140,7 @@ try:
|
| import simplejson as json
|
| except ImportError:
|
| import json
|
| +
|
| from boto.connection import AWSQueryConnection
|
| from boto.ec2.cloudwatch.metric import Metric
|
| from boto.ec2.cloudwatch.alarm import MetricAlarm, AlarmHistoryItem
|
| @@ -151,6 +152,7 @@ RegionData = {
|
| 'us-east-1' : 'monitoring.us-east-1.amazonaws.com',
|
| 'us-west-1' : 'monitoring.us-west-1.amazonaws.com',
|
| 'eu-west-1' : 'monitoring.eu-west-1.amazonaws.com',
|
| + 'ap-northeast-1' : 'monitoring.ap-northeast-1.amazonaws.com',
|
| 'ap-southeast-1' : 'monitoring.ap-southeast-1.amazonaws.com'}
|
|
|
| def regions():
|
| @@ -188,8 +190,10 @@ def connect_to_region(region_name, **kw_params):
|
| class CloudWatchConnection(AWSQueryConnection):
|
|
|
| APIVersion = boto.config.get('Boto', 'cloudwatch_version', '2010-08-01')
|
| - DefaultRegionName = boto.config.get('Boto', 'cloudwatch_region_name', 'us-east-1')
|
| - DefaultRegionEndpoint = boto.config.get('Boto', 'cloudwatch_region_endpoint',
|
| + DefaultRegionName = boto.config.get('Boto', 'cloudwatch_region_name',
|
| + 'us-east-1')
|
| + DefaultRegionEndpoint = boto.config.get('Boto',
|
| + 'cloudwatch_region_endpoint',
|
| 'monitoring.amazonaws.com')
|
|
|
|
|
| @@ -218,21 +222,108 @@ class CloudWatchConnection(AWSQueryConnection):
|
| def _required_auth_capability(self):
|
| return ['ec2']
|
|
|
| + def build_dimension_param(self, dimension, params):
|
| + for dim_name in dimension:
|
| + dim_value = dimension[dim_name]
|
| + if isinstance(dim_value, basestring):
|
| + dim_value = [dim_value]
|
| + for i, value in enumerate(dim_value):
|
| + params['Dimensions.member.%d.Name' % (i+1)] = dim_name
|
| + params['Dimensions.member.%d.Value' % (i+1)] = value
|
| +
|
| def build_list_params(self, params, items, label):
|
| - if isinstance(items, str):
|
| + if isinstance(items, basestring):
|
| items = [items]
|
| - for i in range(1, len(items)+1):
|
| - params[label % i] = items[i-1]
|
| + for index, item in enumerate(items):
|
| + i = index + 1
|
| + if isinstance(item, dict):
|
| + for k,v in item.iteritems():
|
| + params[label % (i, 'Name')] = k
|
| + if v is not None:
|
| + params[label % (i, 'Value')] = v
|
| + else:
|
| + params[label % i] = item
|
| +
|
| + def build_put_params(self, params, name, value=None, timestamp=None,
|
| + unit=None, dimensions=None, statistics=None):
|
| + args = (name, value, unit, dimensions, statistics)
|
| + length = max(map(lambda a: len(a) if isinstance(a, list) else 1, args))
|
| +
|
| + def aslist(a):
|
| + if isinstance(a, list):
|
| + if len(a) != length:
|
| + raise Exception('Must specify equal number of elements; expected %d.' % length)
|
| + return a
|
| + return [a] * length
|
| +
|
| + for index, (n, v, u, d, s) in enumerate(zip(*map(aslist, args))):
|
| + metric_data = {'MetricName': n}
|
| +
|
| + if timestamp:
|
| + metric_data['Timestamp'] = timestamp.isoformat()
|
| +
|
| + if unit:
|
| + metric_data['Unit'] = u
|
| +
|
| + if dimensions:
|
| + self.build_dimension_param(d, metric_data)
|
| +
|
| + if statistics:
|
| + metric_data['StatisticValues.Maximum'] = s['maximum']
|
| + metric_data['StatisticValues.Minimum'] = s['minimum']
|
| + metric_data['StatisticValues.SampleCount'] = s['samplecount']
|
| + metric_data['StatisticValues.Sum'] = s['sum']
|
| + if value != None:
|
| + msg = 'You supplied a value and statistics for a metric.'
|
| + msg += 'Posting statistics and not value.'
|
| + boto.log.warn(msg)
|
| + elif value != None:
|
| + metric_data['Value'] = v
|
| + else:
|
| + raise Exception('Must specify a value or statistics to put.')
|
| +
|
| + for key, value in metric_data.iteritems():
|
| + params['MetricData.member.%d.%s' % (index + 1, key)] = value
|
|
|
| def get_metric_statistics(self, period, start_time, end_time, metric_name,
|
| - namespace, statistics, dimensions=None, unit=None):
|
| + namespace, statistics, dimensions=None,
|
| + unit=None):
|
| """
|
| Get time-series data for one or more statistics of a given metric.
|
|
|
| + :type period: integer
|
| + :param period: The granularity, in seconds, of the returned datapoints.
|
| + Period must be at least 60 seconds and must be a multiple
|
| + of 60. The default value is 60.
|
| +
|
| + :type start_time: datetime
|
| + :param start_time: The time stamp to use for determining the first
|
| + datapoint to return. The value specified is
|
| + inclusive; results include datapoints with the
|
| + time stamp specified.
|
| +
|
| + :type end_time: datetime
|
| + :param end_time: The time stamp to use for determining the last
|
| + datapoint to return. The value specified is
|
| + exclusive; results will include datapoints up to
|
| + the time stamp specified.
|
| +
|
| :type metric_name: string
|
| - :param metric_name: CPUUtilization|NetworkIO-in|NetworkIO-out|DiskIO-ALL-read|
|
| - DiskIO-ALL-write|DiskIO-ALL-read-bytes|DiskIO-ALL-write-bytes
|
| + :param metric_name: The metric name.
|
| +
|
| + :type namespace: string
|
| + :param namespace: The metric's namespace.
|
| +
|
| + :type statistics: list
|
| + :param statistics: A list of statistics names Valid values:
|
| + Average | Sum | SampleCount | Maximum | Minimum
|
|
|
| + :type dimensions: dict
|
| + :param dimensions: A dictionary of dimension key/values where
|
| + the key is the dimension name and the value
|
| + is either a scalar value or an iterator
|
| + of values to be associated with that
|
| + dimension.
|
| :rtype: list
|
| """
|
| params = {'Period' : period,
|
| @@ -242,31 +333,106 @@ class CloudWatchConnection(AWSQueryConnection):
|
| 'EndTime' : end_time.isoformat()}
|
| self.build_list_params(params, statistics, 'Statistics.member.%d')
|
| if dimensions:
|
| - i = 1
|
| - for name in dimensions:
|
| - params['Dimensions.member.%d.Name' % i] = name
|
| - params['Dimensions.member.%d.Value' % i] = dimensions[name]
|
| - i += 1
|
| - return self.get_list('GetMetricStatistics', params, [('member', Datapoint)])
|
| + self.build_dimension_param(dimensions, params)
|
| + return self.get_list('GetMetricStatistics', params,
|
| + [('member', Datapoint)])
|
|
|
| - def list_metrics(self, next_token=None):
|
| + def list_metrics(self, next_token=None, dimensions=None,
|
| + metric_name=None, namespace=None):
|
| """
|
| - Returns a list of the valid metrics for which there is recorded data available.
|
| + Returns a list of the valid metrics for which there is recorded
|
| + data available.
|
|
|
| - :type next_token: string
|
| - :param next_token: A maximum of 500 metrics will be returned at one time.
|
| - If more results are available, the ResultSet returned
|
| - will contain a non-Null next_token attribute. Passing
|
| - that token as a parameter to list_metrics will retrieve
|
| - the next page of metrics.
|
| + :type next_token: str
|
| + :param next_token: A maximum of 500 metrics will be returned at one
|
| + time. If more results are available, the
|
| + ResultSet returned will contain a non-Null
|
| + next_token attribute. Passing that token as a
|
| + parameter to list_metrics will retrieve the
|
| + next page of metrics.
|
| +
|
| + :type dimension: dict
|
| + :param dimension_filters: A dictionary containing name/value pairs
|
| + that will be used to filter the results.
|
| + The key in the dictionary is the name of
|
| + a Dimension. The value in the dictionary
|
| + is either a scalar value of that Dimension
|
| + name that you want to filter on, a list
|
| + of values to filter on or None if
|
| + you want all metrics with that Dimension name.
|
| +
|
| + :type metric_name: str
|
| + :param metric_name: The name of the Metric to filter against. If None,
|
| + all Metric names will be returned.
|
| +
|
| + :type namespace: str
|
| + :param namespace: A Metric namespace to filter against (e.g. AWS/EC2).
|
| + If None, Metrics from all namespaces will be returned.
|
| """
|
| params = {}
|
| if next_token:
|
| params['NextToken'] = next_token
|
| + if dimensions:
|
| + self.build_dimension_param(dimensions, params)
|
| + if metric_name:
|
| + params['MetricName'] = metric_name
|
| + if namespace:
|
| + params['Namespace'] = namespace
|
| +
|
| return self.get_list('ListMetrics', params, [('member', Metric)])
|
| +
|
| + def put_metric_data(self, namespace, name, value=None, timestamp=None,
|
| + unit=None, dimensions=None, statistics=None):
|
| + """
|
| + Publishes metric data points to Amazon CloudWatch. Amazon Cloudwatch
|
| + associates the data points with the specified metric. If the specified
|
| + metric does not exist, Amazon CloudWatch creates the metric. If a list
|
| + is specified for some, but not all, of the arguments, the remaining
|
| + arguments are repeated a corresponding number of times.
|
| +
|
| + :type namespace: str
|
| + :param namespace: The namespace of the metric.
|
|
|
| - def describe_alarms(self, action_prefix=None, alarm_name_prefix=None, alarm_names=None,
|
| - max_records=None, state_value=None, next_token=None):
|
| + :type name: str or list
|
| + :param name: The name of the metric.
|
| +
|
| + :type value: float or list
|
| + :param value: The value for the metric.
|
| +
|
| + :type timestamp: datetime or list
|
| + :param timestamp: The time stamp used for the metric. If not specified,
|
| + the default value is set to the time the metric data was received.
|
| +
|
| + :type unit: string or list
|
| + :param unit: The unit of the metric. Valid Values: Seconds |
|
| + Microseconds | Milliseconds | Bytes | Kilobytes |
|
| + Megabytes | Gigabytes | Terabytes | Bits | Kilobits |
|
| + Megabits | Gigabits | Terabits | Percent | Count |
|
| + Bytes/Second | Kilobytes/Second | Megabytes/Second |
|
| + Gigabytes/Second | Terabytes/Second | Bits/Second |
|
| + Kilobits/Second | Megabits/Second | Gigabits/Second |
|
| + Terabits/Second | Count/Second | None
|
| +
|
| + :type dimensions: dict
|
| + :param dimensions: Add extra name value pairs to associate
|
| + with the metric, i.e.:
|
| + {'name1': value1, 'name2': (value2, value3)}
|
| +
|
| + :type statistics: dict or list
|
| + :param statistics: Use a statistic set instead of a value, for example::
|
| +
|
| + {'maximum': 30, 'minimum': 1, 'samplecount': 100, 'sum': 10000}
|
| + """
|
| + params = {'Namespace': namespace}
|
| + self.build_put_params(params, name, value=value, timestamp=timestamp,
|
| + unit=unit, dimensions=dimensions, statistics=statistics)
|
| +
|
| + return self.get_status('PutMetricData', params)
|
| +
|
| +
|
| + def describe_alarms(self, action_prefix=None, alarm_name_prefix=None,
|
| + alarm_names=None, max_records=None, state_value=None,
|
| + next_token=None):
|
| """
|
| Retrieves alarms with the specified names. If no name is specified, all
|
| alarms for the user are returned. Alarms can be retrieved by using only
|
| @@ -277,20 +443,22 @@ class CloudWatchConnection(AWSQueryConnection):
|
| :param action_name: The action name prefix.
|
|
|
| :type alarm_name_prefix: string
|
| - :param alarm_name_prefix: The alarm name prefix. AlarmNames cannot be specified
|
| - if this parameter is specified.
|
| + :param alarm_name_prefix: The alarm name prefix. AlarmNames cannot
|
| + be specified if this parameter is specified.
|
|
|
| :type alarm_names: list
|
| :param alarm_names: A list of alarm names to retrieve information for.
|
|
|
| :type max_records: int
|
| - :param max_records: The maximum number of alarm descriptions to retrieve.
|
| + :param max_records: The maximum number of alarm descriptions
|
| + to retrieve.
|
|
|
| :type state_value: string
|
| :param state_value: The state value to be used in matching alarms.
|
|
|
| :type next_token: string
|
| - :param next_token: The token returned by a previous call to indicate that there is more data.
|
| + :param next_token: The token returned by a previous call to
|
| + indicate that there is more data.
|
|
|
| :rtype list
|
| """
|
| @@ -307,10 +475,13 @@ class CloudWatchConnection(AWSQueryConnection):
|
| params['NextToken'] = next_token
|
| if state_value:
|
| params['StateValue'] = state_value
|
| - return self.get_list('DescribeAlarms', params, [('member', MetricAlarm)])
|
| + return self.get_list('DescribeAlarms', params,
|
| + [('member', MetricAlarm)])
|
|
|
| - def describe_alarm_history(self, alarm_name=None, start_date=None, end_date=None,
|
| - max_records=None, history_item_type=None, next_token=None):
|
| + def describe_alarm_history(self, alarm_name=None,
|
| + start_date=None, end_date=None,
|
| + max_records=None, history_item_type=None,
|
| + next_token=None):
|
| """
|
| Retrieves history for the specified alarm. Filter alarms by date range
|
| or item type. If an alarm name is not specified, Amazon CloudWatch
|
| @@ -330,13 +501,16 @@ class CloudWatchConnection(AWSQueryConnection):
|
| :param end_date: The starting date to retrieve alarm history.
|
|
|
| :type history_item_type: string
|
| - :param history_item_type: The type of alarm histories to retreive (ConfigurationUpdate | StateUpdate | Action)
|
| + :param history_item_type: The type of alarm histories to retreive
|
| + (ConfigurationUpdate | StateUpdate | Action)
|
|
|
| :type max_records: int
|
| - :param max_records: The maximum number of alarm descriptions to retrieve.
|
| + :param max_records: The maximum number of alarm descriptions
|
| + to retrieve.
|
|
|
| :type next_token: string
|
| - :param next_token: The token returned by a previous call to indicate that there is more data.
|
| + :param next_token: The token returned by a previous call to indicate
|
| + that there is more data.
|
|
|
| :rtype list
|
| """
|
| @@ -353,9 +527,11 @@ class CloudWatchConnection(AWSQueryConnection):
|
| params['MaxRecords'] = max_records
|
| if next_token:
|
| params['NextToken'] = next_token
|
| - return self.get_list('DescribeAlarmHistory', params, [('member', AlarmHistoryItem)])
|
| + return self.get_list('DescribeAlarmHistory', params,
|
| + [('member', AlarmHistoryItem)])
|
|
|
| - def describe_alarms_for_metric(self, metric_name, namespace, period=None, statistic=None, dimensions=None, unit=None):
|
| + def describe_alarms_for_metric(self, metric_name, namespace, period=None,
|
| + statistic=None, dimensions=None, unit=None):
|
| """
|
| Retrieves all alarms for a single metric. Specify a statistic, period,
|
| or unit to filter the set of alarms further.
|
| @@ -367,30 +543,37 @@ class CloudWatchConnection(AWSQueryConnection):
|
| :param namespace: The namespace of the metric.
|
|
|
| :type period: int
|
| - :param period: The period in seconds over which the statistic is applied.
|
| + :param period: The period in seconds over which the statistic
|
| + is applied.
|
|
|
| :type statistic: string
|
| :param statistic: The statistic for the metric.
|
|
|
| - :type dimensions: list
|
| + :param dimension_filters: A dictionary containing name/value pairs
|
| + that will be used to filter the results.
|
| + The key in the dictionary is the name of
|
| + a Dimension. The value in the dictionary
|
| + is either a scalar value of that Dimension
|
| + name that you want to filter on, a list
|
| + of values to filter on or None if
|
| + you want all metrics with that Dimension name.
|
|
|
| :type unit: string
|
|
|
| :rtype list
|
| """
|
| - params = {
|
| - 'MetricName' : metric_name,
|
| - 'Namespace' : namespace,
|
| - }
|
| + params = {'MetricName' : metric_name,
|
| + 'Namespace' : namespace}
|
| if period:
|
| params['Period'] = period
|
| if statistic:
|
| params['Statistic'] = statistic
|
| if dimensions:
|
| - self.build_list_params(params, dimensions, 'Dimensions.member.%s')
|
| + self.build_dimension_param(dimensions, params)
|
| if unit:
|
| params['Unit'] = unit
|
| - return self.get_list('DescribeAlarmsForMetric', params, [('member', MetricAlarm)])
|
| + return self.get_list('DescribeAlarmsForMetric', params,
|
| + [('member', MetricAlarm)])
|
|
|
| def put_metric_alarm(self, alarm):
|
| """
|
| @@ -413,7 +596,7 @@ class CloudWatchConnection(AWSQueryConnection):
|
| 'MetricName' : alarm.metric,
|
| 'Namespace' : alarm.namespace,
|
| 'Statistic' : alarm.statistic,
|
| - 'ComparisonOperator' : MetricAlarm._cmp_map[alarm.comparison],
|
| + 'ComparisonOperator' : alarm.comparison,
|
| 'Threshold' : alarm.threshold,
|
| 'EvaluationPeriods' : alarm.evaluation_periods,
|
| 'Period' : alarm.period,
|
| @@ -421,15 +604,18 @@ class CloudWatchConnection(AWSQueryConnection):
|
| if alarm.actions_enabled is not None:
|
| params['ActionsEnabled'] = alarm.actions_enabled
|
| if alarm.alarm_actions:
|
| - self.build_list_params(params, alarm.alarm_actions, 'AlarmActions.member.%s')
|
| + self.build_list_params(params, alarm.alarm_actions,
|
| + 'AlarmActions.member.%s')
|
| if alarm.description:
|
| params['AlarmDescription'] = alarm.description
|
| if alarm.dimensions:
|
| - self.build_list_params(params, alarm.dimensions, 'Dimensions.member.%s')
|
| + self.build_dimension_param(alarm.dimensions, params)
|
| if alarm.insufficient_data_actions:
|
| - self.build_list_params(params, alarm.insufficient_data_actions, 'InsufficientDataActions.member.%s')
|
| + self.build_list_params(params, alarm.insufficient_data_actions,
|
| + 'InsufficientDataActions.member.%s')
|
| if alarm.ok_actions:
|
| - self.build_list_params(params, alarm.ok_actions, 'OKActions.member.%s')
|
| + self.build_list_params(params, alarm.ok_actions,
|
| + 'OKActions.member.%s')
|
| if alarm.unit:
|
| params['Unit'] = alarm.unit
|
| alarm.connection = self
|
| @@ -439,7 +625,8 @@ class CloudWatchConnection(AWSQueryConnection):
|
|
|
| def delete_alarms(self, alarms):
|
| """
|
| - Deletes all specified alarms. In the event of an error, no alarms are deleted.
|
| + Deletes all specified alarms. In the event of an error, no
|
| + alarms are deleted.
|
|
|
| :type alarms: list
|
| :param alarms: List of alarm names.
|
| @@ -448,7 +635,8 @@ class CloudWatchConnection(AWSQueryConnection):
|
| self.build_list_params(params, alarms, 'AlarmNames.member.%s')
|
| return self.get_status('DeleteAlarms', params)
|
|
|
| - def set_alarm_state(self, alarm_name, state_reason, state_value, state_reason_data=None):
|
| + def set_alarm_state(self, alarm_name, state_reason, state_value,
|
| + state_reason_data=None):
|
| """
|
| Temporarily sets the state of an alarm. When the updated StateValue
|
| differs from the previous value, the action configured for the
|
| @@ -468,11 +656,9 @@ class CloudWatchConnection(AWSQueryConnection):
|
| :type state_reason_data: string
|
| :param state_reason_data: Reason string (will be jsonified).
|
| """
|
| - params = {
|
| - 'AlarmName' : alarm_name,
|
| - 'StateReason' : state_reason,
|
| - 'StateValue' : state_value,
|
| - }
|
| + params = {'AlarmName' : alarm_name,
|
| + 'StateReason' : state_reason,
|
| + 'StateValue' : state_value}
|
| if state_reason_data:
|
| params['StateReasonData'] = json.dumps(state_reason_data)
|
|
|
|
|