def test_schedule_service(self): zk_client = None options.define('private_ip', '192.168.33.10') manager = ServiceManager(zk_client) # Test that servers are started when scheduled. manager._schedule_service(ServiceTypes.DATASTORE, {'count': 2, 'verbose': False}) self.assertEqual(len(manager.state), 2)
def test_get_state(self): # Test that server objects are created with the correct PIDs. with patch('appscale.admin.service_manager.pids_in_slice', return_value=[10000, 10001]): with patch.object(DatastoreServer, 'from_pid') as mock_from_pid: ServiceManager.get_state() self.assertEqual(mock_from_pid.call_count, 2) for index, expected_pid in enumerate((10000, 10001)): self.assertEqual(mock_from_pid.call_args_list[index][0][0], expected_pid)
def test_get_state(self): cgroup_file = io.StringIO(u'10000\n10001') # Test that server objects are created with the correct PIDs. with patch('appscale.admin.service_manager.open', return_value=cgroup_file): with patch.object(DatastoreServer, 'from_pid') as mock_from_pid: ServiceManager.get_state() self.assertEqual(mock_from_pid.call_count, 2) for index, expected_pid in enumerate((10000, 10001)): self.assertEqual(mock_from_pid.call_args_list[index][0][0], expected_pid)
def test_schedule_service(self): zk_client = None if not hasattr(options, 'private_ip'): options.define('private_ip', '192.168.33.10') manager = ServiceManager(zk_client) # Test that servers are started when scheduled. manager._schedule_service(ServiceTypes.DATASTORE, { 'count': 2, 'verbose': False }) self.assertEqual(len(manager.state), 2)
def get_service_summary(self, secret): """ Retrieves Monit's summary on this node. Args: secret: The secret of the deployment; used for authentication. Returns: A dictionary containing Monit's summary as a string. """ if self.secret != secret: return self.__generate_response( False, InfrastructureManager.REASON_BAD_SECRET) monit_stats = subprocess.check_output(["monit", "summary"]) monit_stats_dict = {} for line in monit_stats.split("\n"): tokens = line.split() if 'Process' in tokens: process_name = tokens[1][1:-1] # Remove quotes. process_status = ' '.join(tokens[2:]).lower() monit_stats_dict[process_name] = process_status logging.debug("Monit stats: {}".format(monit_stats_dict)) # Get status of processes managed by the ServiceManager. monit_stats_dict.update({ '-'.join([server.type, str(server.port)]): server.state for server in ServiceManager.get_state() }) return json.dumps(monit_stats_dict)
def test_get_state(self, pids_in_slice_mock, from_pid_mock): # Test that server objects are created with the correct PIDs. slices = { 'appscale-datastore': [10000, 10001], 'appscale-search': [15000, 15001] } pids_in_slice_mock.side_effect = lambda service_type: slices[ service_type] ServiceManager.get_state() self.assertEqual(from_pid_mock.call_count, 4) calls = from_pid_mock.call_args_list self.assertEqual(calls[0], call(10000, datastore_service)) self.assertEqual(calls[1], call(10001, datastore_service)) self.assertEqual(calls[2], call(15000, search_service)) self.assertEqual(calls[3], call(15001, search_service))
def get_service_summary(cls): """ Retrieves Monit's summary on this node. Returns: A dictionary containing Monit's summary as a string. """ try: monit_stats = subprocess.check_output(["monit", "summary"]) except subprocess.CalledProcessError: logger.warn("get_service_summary: failed to query monit.") raise ServiceException('Failed to query monit.') monit_stats_dict = {} for line in monit_stats.split("\n"): tokens = line.split() if 'Process' in tokens: process_name = tokens[1][1:-1] # Remove quotes. process_status = ' '.join(tokens[2:]).lower() monit_stats_dict[process_name] = process_status logger.debug("Monit stats: {}".format(monit_stats_dict)) # Get status of processes managed by the ServiceManager. monit_stats_dict.update({ '-'.join([server.type, str(server.port)]): server.state for server in ServiceManager.get_state() }) return monit_stats_dict
def get_service_summary(self, secret): """ Retrieves Monit's summary on this node. Args: secret: The secret of the deployment; used for authentication. Returns: A dictionary containing Monit's summary as a string. """ if self.secret != secret: return self.__generate_response(False, InfrastructureManager.REASON_BAD_SECRET) try: monit_stats = subprocess.check_output(["monit", "summary"]) except CalledProcessError: logging.warn("get_service_summary: failed to query monit.") raise ServiceException('Failed to query monit.') monit_stats_dict = {} for line in monit_stats.split("\n"): tokens = line.split() if 'Process' in tokens: process_name = tokens[1][1:-1] # Remove quotes. process_status = ' '.join(tokens[2:]).lower() monit_stats_dict[process_name] = process_status logging.debug("Monit stats: {}".format(monit_stats_dict)) # Get status of processes managed by the ServiceManager. monit_stats_dict.update( {'-'.join([server.type, str(server.port)]): server.state for server in ServiceManager.get_state()}) return json.dumps(monit_stats_dict)
def get_services(): """ Get dictionary of services from ServiceManager. Returns: A dictionary mapping service name to service state. """ servers = { '-'.join([server.type, str(server.port)]): server.state for server in ServiceManager.get_state() } return servers
def get_combined_services(): """ Merge list of services from Monit and ServiceManager. Returns: A dictionary mapping service name to service state. """ http_client = HTTPClient() status_url = '{}/_status?format=xml'.format(MonitOperator.LOCATION) response = http_client.fetch(status_url) servers = parse_entries(response.body) servers.update({ '-'.join([server.type, str(server.port)]): server.state for server in ServiceManager.get_state() }) return servers
def get_current(): """ Method for building a list of ProcessStats. It parses output of `systemctl show` and generates ProcessStats object for each service of interest. Returns: An instance ofProcessesStatsSnapshot. """ start = time.time() systemctl_show = subprocess.check_output(SYSTEMCTL_SHOW).decode() processes_stats = [] private_ip = appscale_info.get_private_ip() for match in SYSTEMCTL_SHOW_PATTERN.finditer(systemctl_show): systemd_name = match.group('name') pid = int(match.group('pid')) service = find_service_by_external_name( systemd_name, default_mapper=systemd_mapper) if service is None: continue try: stats = _process_stats(pid, service, systemd_name, private_ip) processes_stats.append(stats) except psutil.Error as err: logger.warning( "Unable to get process stats for {name} ({err})".format( name=service.name, err=err)) # Add processes managed by the ServiceManager. for server in ServiceManager.get_state(): service = find_service_by_external_name(server.monit_name) try: stats = _process_stats(server.process.pid, service, server.monit_name, private_ip) processes_stats.append(stats) except psutil.Error as error: logger.warning('Unable to get process stats for ' '{} ({})'.format(server, error)) stats = ProcessesStatsSnapshot(utc_timestamp=time.mktime( datetime.now().timetuple()), processes_stats=processes_stats) logger.info( "Prepared stats about {proc} processes in {elapsed:.1f}s.".format( proc=len(processes_stats), elapsed=time.time() - start)) return stats
def get_current(): """ Method for building a list of ProcessStats. It parses output of `monit status` and generates ProcessStats object for each monitored service. Returns: An instance ofProcessesStatsSnapshot. """ start = time.time() monit_status = subprocess.check_output('monit status', shell=True).decode() processes_stats = [] private_ip = appscale_info.get_private_ip() for match in MONIT_PROCESS_PATTERN.finditer(monit_status): monit_name = match.group('name') pid = int(match.group('pid')) service = find_service_by_monit_name(monit_name) try: stats = _process_stats(pid, service, monit_name, private_ip) processes_stats.append(stats) except psutil.Error as err: logger.warning( "Unable to get process stats for {monit_name} ({err})". format(monit_name=monit_name, err=err)) # Add processes managed by the ServiceManager. for server in ServiceManager.get_state(): service = find_service_by_monit_name(server.monit_name) try: stats = _process_stats(server.process.pid, service, server.monit_name, private_ip) processes_stats.append(stats) except psutil.Error as error: logger.warning('Unable to get process stats for ' '{} ({})'.format(server, error)) stats = ProcessesStatsSnapshot(utc_timestamp=time.mktime( datetime.now().timetuple()), processes_stats=processes_stats) logger.info( "Prepared stats about {proc} processes in {elapsed:.1f}s.".format( proc=len(processes_stats), elapsed=time.time() - start)) return stats
def get_current(): """ Method for building a list of ProcessStats. It parses output of `monit status` and generates ProcessStats object for each monitored service. Returns: An instance ofProcessesStatsSnapshot. """ start = time.time() monit_status = subprocess.check_output('monit status', shell=True) processes_stats = [] private_ip = appscale_info.get_private_ip() for match in MONIT_PROCESS_PATTERN.finditer(monit_status): monit_name = match.group('name') pid = int(match.group('pid')) service = find_service_by_monit_name(monit_name) try: stats = _process_stats(pid, service, monit_name, private_ip) processes_stats.append(stats) except psutil.Error as err: logging.warn(u"Unable to get process stats for {monit_name} ({err})" .format(monit_name=monit_name, err=err)) # Add processes managed by the ServiceManager. for server in ServiceManager.get_state(): service = find_service_by_monit_name(server.monit_name) try: stats = _process_stats(server.process.pid, service, server.monit_name, private_ip) processes_stats.append(stats) except psutil.Error as error: logging.warning(u'Unable to get process stats for ' u'{} ({})'.format(server, error)) stats = ProcessesStatsSnapshot( utc_timestamp=time.mktime(datetime.now().timetuple()), processes_stats=processes_stats ) logging.info("Prepared stats about {proc} processes in {elapsed:.1f}s." .format(proc=len(processes_stats), elapsed=time.time()-start)) return stats
def test_schedule_service(self, options_mock): options_mock.private_ip = '192.168.33.10' zk_client = None manager = ServiceManager(zk_client) # Test that servers are started when scheduled. manager._schedule_service(ServiceTypes.DATASTORE, { 'count': 2, 'verbose': False }) self.assertEqual(len(manager.state), 2) manager._schedule_service(ServiceTypes.SEARCH, { 'count': 3, 'verbose': True }) self.assertEqual(len(manager.state), 5)