def gather_statistics_data(self): start_time = datetime.utcnow() log.debug('gather_statistics_data job started') computation_nodes = self.api_requests.get_all_computation_nodes_info( ).json() log.info('computation nodes: %s', computation_nodes) for node in computation_nodes: node_name = node['name'] log.debug('started retrieving node details for %s', node_name) node_details = self.api_requests.get_computation_node_details( node_name).json() log.info('node details for %s received: %s', node_name, node_details) node_address = node_details['address'] node_port = node_details['port'] backend_requests = BackendRequests('{0}:{1}'.format( node_address, node_port)) for device in node_details['backend_info']['devices']: self._gather_device_stats(node_name, device, backend_requests) finish_time = datetime.utcnow() log.info('gather_statistics_data job finished, it took %s seconds', (finish_time - start_time).total_seconds())
def run_rules(self): start_time = datetime.utcnow() log.debug('run_rules job started') rule_types = rules.Rule.__subclasses__() # pylint: disable=no-member computation_nodes = self.api_requests.get_all_computation_nodes_info( ).json() log.info('computation nodes: %s', computation_nodes) for node in computation_nodes: node_name = node['name'] log.debug('started retrieving node details for %s', node_name) node_details = self.api_requests.get_computation_node_details( node_name).json() log.info('node details for %s received: %s', node_name, node_details) for device in node_details['backend_info']['devices']: self._run_rule_for_device(node_name, device, rule_types) finish_time = datetime.utcnow() log.info('run_rules job finished, it took %s seconds', (finish_time - start_time).total_seconds())
def parse_args(argv): parser = create_parser() log.debug("parser created") add_arguments_to_parser(parser) args = parser.parse_args(argv) log.debug("arguments parsed") return args
def proceed(self, rule_params: Dict): log.debug("proceeding Withdrawable rule for %s:%s with params %s", self.node_name, self.device_id, rule_params) current_minute = datetime.utcnow().replace(second=0, microsecond=0) deadline_str = rule_params.get("deadline") deadline = datetime.strptime(deadline_str, '%Y-%m-%dT%H:%M') if deadline_str else None if rule_params.get("withdraw", False) or deadline and deadline < current_minute: if rule_params.get("previous_rule"): self.api_requests.put_rule_for_device(self.node_name, self.device_id, rule_params["previous_rule"]) else: self.api_requests.delete_rule_for_device(self.node_name, self.device_id) self.set_limit_on_device(rule_params)
def _gather_device_stats(self, node_name, device, backend_requests): device_id = device['id'] device_type = device['Type'] response = self.api_requests.get_statistics_interval_info( node_name, device_id) if response.status_code != 200: log.debug('no statistics interval info for %s', device_id) return interval_info = response.json() log.debug('interval info for %s: %s', device_id, interval_info) next_measurement = datetime.strptime(interval_info['next_measurement'], '%Y-%m-%dT%H:%M') current_time = datetime.utcnow() if next_measurement > current_time: log.debug('no need to gather statistics data now') return response = backend_requests.get_power_usage_for_device( device_type, device_id) usage = response.json() self.api_requests.put_statistics_data( node_name, device_id, interval_info['next_measurement'], usage[0]['PowerUsage']) log.debug('stored statistics data for %s: %s', node_name, device_id)
def proceed(self, rule_params): log.debug("proceeding TimeBased rule for %s:%s with params %s", self.node_name, self.device_id, rule_params) self._parse_params(rule_params) current_minute = datetime.utcnow().replace(second=0, microsecond=0) limit_to_set = None for subrule in self.subrules: if subrule['start'] <= current_minute < subrule['end']: limit_to_set = subrule['limit'] break current_limit_response = self.api_requests.get_power_limit_info(self.node_name, self.device_id) if current_limit_response.status_code != 200: current_limit = None else: current_limit = int(current_limit_response.json()['power_limit']) if limit_to_set == current_limit: return if limit_to_set is None: self.api_requests.delete_power_limit_info(self.node_name, self.device_id) return self.api_requests.put_power_limit_info(self.node_name, self.device_id, limit_to_set)
def _update_device_power_limit(self, device, node_name, backend_requests): device_id = device['id'] device_type = device[ 'Type'] # probably temporary - device_type is necessary for backend queries log.debug('started retrieving power limit info for %s:%s', node_name, device_id) power_limit_response = self.api_requests.get_power_limit_info( node_name, device_id) if power_limit_response.status_code == 404: log.info('no power limit info set in database for %s:%s', node_name, device_id) else: power_limit = power_limit_response.json() log.info('power limit info for %s:%s received: %s', node_name, device_id, power_limit) log.debug('started retrieving power limit info from device %s:%s', node_name, device_id) device_power_limit = backend_requests.get_power_limit_for_device( device_type, device_id).json()[0]['PowerLimit'] # Naive implementation log.info('power limit info from device %s:%s received: %s', node_name, device_id, device_power_limit) if device_power_limit != int(power_limit['power_limit']): log.debug('setting power limit for device %s:%s to %s', node_name, device_id, int(power_limit['power_limit'])) resp = backend_requests.set_power_limit_for_device( device_type, device_id, int(power_limit['power_limit'])) log.info('set power limit for device %s:%s, response: %s', node_name, device_id, resp.text)
def proceed(self, rule_params): log.debug("proceeding HardLimit rule for %s:%s with params %s", self.node_name, self.device_id, rule_params) self.set_limit_on_device(rule_params)
def parse_config_file(config_file_path): config = configparser.ConfigParser() config.read(config_file_path) log.debug("Application configuration loaded from %s", config_file_path) return config
def configure_logging(config_file_path): logging.config.fileConfig(config_file_path) log.debug("Logging configuration loaded from %s", config_file_path)
def create_parser(): log.debug("creating argument parser") return argparse.ArgumentParser(description="HPC Power Management - Management")