def latency_write_log(self): # TODO log the latency data every 10 cycle at INFO level for component_name in self.component_names(): if self.latency[(component_name, 'total-time')] == 0: self.logger.debug('No latency data for %s' % component_name) continue avg_latency = float(self.latency[(component_name, 'total-time')] / self.latency[(component_name, 'num-samples')]) max_latency = self.latency[(component_name, 'max-latency')] self.logger.debug('Metric:%s:avg-latency: %s' % (component_name, avg_latency)) self.logger.debug('Metric:%s:max-latency: %s' % (component_name, max_latency)) dimensions = common_dimensions.copy() dimensions['component'] = component_name if component_name == COMPONENT_KEYSTONE_GET_TOKEN: dimensions['url'] = self.authurl else: dimensions['url'] = self.object_store_url self.metric_data.append( dict(metric=AVG_LATENCY, value=avg_latency, dimensions=dimensions, timestamp=timestamp())) self.metric_data.append( dict(metric=MAX_LATENCY, value=max_latency, dimensions=dimensions, timestamp=timestamp()))
def duration(self): """Context manager to set duration and timestamp.""" start = timestamp() yield self._timestamp = end = timestamp() if isinstance(end, datetime.timedelta): self['duration'] = (end - start).total_seconds() else: self['duration'] = str(end - start)
def latency_write_log(self): now = time.time() for component_name in self.component_names(): if self.latency[(component_name, 'total-time')] == 0: self.logger.info('No latency data for %s' % component_name) continue if self.latency[(component_name, 'min-latency')] is None: self.latency[(component_name, 'min-latency')] = 0.0 min_latency = self.latency[(component_name, 'min-latency')] max_latency = self.latency[(component_name, 'max-latency')] avg_latency = float(self.latency[(component_name, 'total-time')] / self.latency[(component_name, 'num-samples')]) if (now - self.last_latency_logged) >= LATENCY_LOG_INTERVAL: self.logger.info('Metric:%s:min-latency: %s (at %s)' % (component_name, min_latency, now)) self.logger.info('Metric:%s:max-latency: %s (at %s)' % (component_name, max_latency, now)) self.logger.info('Metric:%s:avg-latency: %s (at %s)' % (component_name, avg_latency, now)) self.last_latency_logged = now dimensions = common_dimensions.copy() dimensions['component'] = component_name if component_name == COMPONENT_KEYSTONE_GET_TOKEN: target_url = self.authurl else: target_url = self.object_store_url target_name = urlparse.urlparse(target_url).hostname dimensions['url'] = target_url dimensions['hostname'] = '_' self.metric_data.append( dict(metric=MIN_LATENCY, value=min_latency, dimensions=dimensions, timestamp=timestamp())) self.metric_data.append( dict(metric=MAX_LATENCY, value=max_latency, dimensions=dimensions, timestamp=timestamp())) self.metric_data.append( dict(metric=AVG_LATENCY, value=avg_latency, dimensions=dimensions, timestamp=timestamp()))
def dump_metric_data(self): self.logger.debug("PRINTING CONTENTS OF METRIC DATA") # Read the component state metrics and append them to metrics_data dict for component_name in self.component_names(): metric = self.state[component_name]['metrics'].copy() # Time is now rather than the time we moved to this state metric['timestamp'] = timestamp() self.metric_data.append(metric) self.logger.debug(self.metric_data) dump_swiftlm_uptime_data(self.metric_data, self.cache_file_path, self.logger)
def record_state(self, sev, component_name, new_state, reason): self.logger.debug(" ++++++++++++++ record_state called %s %s %s %s" % (sev, component_name, new_state, reason)) # Pick out the name (drop https://, port and path) k = component_name + sev if k in self.state.keys(): old_state = self.state[component_name + sev] else: old_state = component_states.unknown state_details = dict(current_state=old_state, reason='', metrics={}) self.state[component_name + severities.info] = state_details self.state[component_name + severities.hard] = state_details if old_state != new_state: now = time.time() state_details = self.state[component_name + sev] state_details['current_state'] = new_state state_details['reason'] = reason dimensions = common_dimensions.copy() dimensions['component'] = component_name if component_name == COMPONENT_KEYSTONE_GET_TOKEN: dimensions['url'] = self.authurl else: dimensions['url'] = self.object_store_url if sev == severities.info: metric_name = INFO_STATE elif sev == severities.hard: metric_name = HARD_STATE else: raise Exception("Invalid severity %s specified" % sev) # Report state as 0 for ok, 1 for failed and 3 for unknown # Monasca alarm expressions support only numerical values hence # report numbers for state so that we can configure alarms in # monasca if new_state == component_states.failed: state_details['metrics'] = \ dict(metric=metric_name, value=STATE_VALUE_FAILED, dimensions=dimensions, timestamp=timestamp(), value_meta={'msg': str(reason)}) elif new_state == component_states.ok: state_details['metrics'] = \ dict(metric=metric_name, value=STATE_VALUE_OK, dimensions=dimensions, timestamp=timestamp()) else: # this condition may not exist, still adding it to # be complete state_details['metrics'] = \ dict(metric=metric_name, value=STATE_VALUE_UNKNOWN, dimensions=dimensions, timestamp=timestamp()) message = '{0} {1} {2}'.format(component_name, new_state, reason) # We need to log all state transitions at INFO level self.logger.info('%s %s %s %s\n' % (time.strftime('%Y%m%d-%H:%M.%S', time.gmtime(now)), now, sev, message.replace('\n', ' ')))
def timestamp(self): self._timestamp = timestamp()
def record_state(self, component_name, new_state, reason): self.logger.debug(" ++++++++++++++ record_state called %s %s %s" % (component_name, new_state, reason)) # Pick out the name (drop https://, port and path) k = component_name if k in self.state.keys(): old_state = self.state[component_name]['current_state'] else: old_state = component_states.unknown state_details = dict(current_state=old_state, reason='', metrics={}) self.state[component_name] = state_details if old_state != new_state: now = time.time() state_details = self.state[component_name] state_details['current_state'] = new_state state_details['reason'] = reason dimensions = common_dimensions.copy() dimensions['component'] = component_name if component_name == COMPONENT_KEYSTONE_GET_TOKEN: target_url = self.authurl else: target_url = self.object_store_url target_name = urlparse.urlparse(target_url).hostname dimensions['url'] = target_url dimensions['hostname'] = '_' # Report state as 0 for ok, 1 for warn, 2 for fail, and 3 for # unknown. Monasca alarm expressions support only numerical # values hence report numbers for state so that we can configure # alarms in monasca if new_state == component_states.fail: state_details['metrics'] = \ dict(metric=SWIFT_STATE, value=STATE_VALUE_FAIL, dimensions=dimensions, timestamp=timestamp(), value_meta={'msg': str(reason).strip('\n')}) elif new_state == component_states.ok: state_details['metrics'] = \ dict(metric=SWIFT_STATE, value=STATE_VALUE_OK, dimensions=dimensions, timestamp=timestamp()) else: # this condition may not exist, still adding it to # be complete state_details['metrics'] = \ dict(metric=SWIFT_STATE, value=STATE_VALUE_UNKNOWN, dimensions=dimensions, timestamp=timestamp()) message = '{0} {1} {2}'.format(component_name, new_state, reason) # We log all state transitions at INFO level self.logger.info('State-change:{component_name}: {new_state}' ' (at {now}): {reason}'.format( **{ 'component_name': component_name, 'new_state': new_state, 'now': now, 'reason': message.replace('\n', ' ') }))