def get_time(self, config_id, ds): key = self._key(config_id, ds) cycletime = (ds.cycletime / 60) * 60 # never collect older than 30 minutes ago. min_timestamp = iso8601(seconds_ago=30*60) timestamp = self._track.get(key) if timestamp is None: # start with cycletime * 4 ago return iso8601(seconds_ago=cycletime * 4) if timestamp_from_cloudwatch(timestamp) < timestamp_from_cloudwatch(min_timestamp): return min_timestamp else: return timestamp
def collect(self, config): ds0 = config.datasources[0] log.debug("Collect for AmazonCloudWatch (%d)" % ds0.zAWSCloudWatchMaxParallel) results = [] if not config.datasources[0].component: log.warn("Amazon CloudWatch data source type " "not suitable to use on device level") defer.returnValue(results) return # Static for performance collection httpVerb = 'GET' uriRequest = '/' baseRequest = {} baseRequest['SignatureMethod'] = 'HmacSHA256' baseRequest['SignatureVersion'] = '2' deferreds = [] for ds in config.datasources: # CloudWatch only accepts periods that are evenly divisible by 60. cycletime = (ds.cycletime / 60) * 60 hostHeader = lookup_cwregion(ds.params['region']) monitorRequest = baseRequest.copy() monitorRequest['Action'] = 'GetMetricStatistics' monitorRequest['Version'] = '2010-08-01' monitorRequest['Period'] = cycletime monitorRequest['StartTime'] = self.lastsuccess.get_time(config.id, ds) monitorRequest['EndTime'] = iso8601() monitorRequest['Namespace'] = ds.params['namespace'] monitorRequest['MetricName'] = ds.params['metric'] monitorRequest['Statistics.member.1'] = ds.params['statistic'] if ds.params['dimension']: dim_group = ds.params['dimension'].split(';') i = 0 for dim_name, dim_value in [x.split('=') for x in dim_group]: i += 1 monitorRequest['Dimensions.member.%d.Name' % i] = dim_name monitorRequest['Dimensions.member.%d.Value' % i] = dim_value getURL = awsUrlSign( httpVerb, hostHeader, uriRequest, monitorRequest, (ds.ec2accesskey, ds.ec2secretkey)) getURL = '{0}://{1}'.format( ('https' if ds.zAWSCloudWatchSSL else 'http'), getURL ) log.debug( "doQuery [%s] StartTime=%s, EndTime=%s", self.ds_description(config, ds), monitorRequest['StartTime'], monitorRequest['EndTime']) d = self.doQuery(config, getURL, ds, monitorRequest['StartTime']) deferreds.append(d) # allow all the requests to complete. results = yield defer.DeferredList(deferreds, consumeErrors=True) # and return their results defer.returnValue([x[1] for x in results])
def collect(self, config): log.debug("Collect for AWS") results = [] ds0 = config.datasources[0] accesskey = ds0.ec2accesskey secretkey = ds0.ec2secretkey # CloudWatch only accepts periods that are evenly divisible by 60. cycletime = (ds0.cycletime / 60) * 60 # Static for performance collection httpVerb = 'GET' uriRequest = '/' baseRequest = {} baseRequest['SignatureMethod'] = 'HmacSHA256' baseRequest['SignatureVersion'] = '2' def sleep(secs): d = defer.Deferred() reactor.callLater(secs, d.callback, None) return d for ds in config.datasources: hostHeader = lookup_cwregion(ds.params['region']) monitorRequest = baseRequest.copy() monitorRequest['Action'] = 'GetMetricStatistics' monitorRequest['Version'] = '2010-08-01' monitorRequest['Period'] = cycletime monitorRequest['StartTime'] = iso8601(seconds_ago=(cycletime * 2)) monitorRequest['EndTime'] = iso8601() monitorRequest['Namespace'] = ds.params['namespace'] monitorRequest['MetricName'] = ds.params['metric'] monitorRequest['Statistics.member.1'] = ds.params['statistic'] if ds.params['dimension']: dim_name, dim_value = ds.params['dimension'].split('=') monitorRequest['Dimensions.member.1.Name'] = dim_name monitorRequest['Dimensions.member.1.Value'] = dim_value getURL = awsUrlSign( httpVerb, hostHeader, uriRequest, monitorRequest, (accesskey, secretkey)) getURL = 'http://%s' % getURL # Incremental backoff as outlined by AWS. # http://aws.amazon.com/articles/1394 for retry in xrange(MAX_RETRIES + 1): if retry > 0: delay = (random.random() * pow(4, retry)) / 10.0 log.debug( '%s (%s): retry %s backoff is %s seconds', config.id, ds.params['region'], retry, delay) wait = yield sleep(delay) try: log.debug( '%s (%s): requesting %s %s/%s for %s', config.id, ds.params['region'], ds.params['statistic'], ds.params['namespace'], ds.params['metric'], ds.params['dimension'] or 'region') result = yield getPage(getURL) except Exception, ex: code = getattr(ex, 'status', None) if code in ('500', '503'): continue raise else: results.append((ds, result)) break if ds.params['metric'] == 'VolumeTotalWriteTime': # Get Volume Status volumeRequest = baseRequest.copy() volumeRequest['Action'] = 'DescribeVolumeStatus' volumeRequest['Version'] = '2013-02-01' volumeRequest['VolumeId.1'] = dim_value hostHeader = 'ec2.amazonaws.com' getURL = awsUrlSign( httpVerb, hostHeader, uriRequest, volumeRequest, [accesskey, secretkey]) getURL = 'http://%s' % getURL log.debug('Get Volume Information: %s', getURL) result = yield getPage(getURL) results.append(('volumestatus', result))