def latest_stats(adapter, host_uuid, include_vio=True): """Returns the latest PHYP and (optionally) VIOS statistics. :param adapter: The pypowervm adapter. :param host_uuid: The host system's UUID. :param include_vio: (Optional) Defaults to True. If set to false, the VIO metrics will always be returned as an empty list. :return: datetime - When the metrics were pulled. :return: phyp_data - The PhypInfo object for the raw metrics. May be None if there are issues gathering the metrics. :return: vios_datas - The list of ViosInfo objects. May be empty if the metrics are unavailable or if the include_vio flag is False. Is a list as the system may have many Virtual I/O Servers. """ ltm_metrics = query_ltm_feed(adapter, host_uuid) latest_phyp = None # Get the latest PHYP metric for metric in ltm_metrics: if metric.category != 'phyp': continue if (latest_phyp is None or latest_phyp.updated_datetime < metric.updated_datetime): latest_phyp = metric # If there is no current metric, return None. if latest_phyp is None: return datetime.datetime.now(), None, None phyp_json = adapter.read_by_href(latest_phyp.link, xag=[]).body phyp_metric = phyp_mon.PhypInfo(phyp_json) # Now find the corresponding VIOS metrics for this. vios_ltms = [] for metric in ltm_metrics: # The VIOS metrics start with the key 'vios_' if not metric.category.startswith('vios_'): continue if metric.updated_datetime == latest_phyp.updated_datetime: vios_ltms.append(metric) if include_vio: vios_metrics = [ vios_mon.ViosInfo(adapter.read_by_href(x.link).body) for x in vios_ltms ] else: vios_metrics = [] return datetime.datetime.now(), phyp_metric, vios_metrics
def test_parse(self): info = pcm_vios.ViosInfo(self.raw_json) self.assertIsNotNone(info) # Validate the info self.assertEqual('1.0.0', info.info.version) self.assertEqual('Raw', info.info.metric_type) self.assertEqual('LTM', info.info.monitoring_type) self.assertEqual('8247-22L*2125D4A', info.info.mtms) # Validate some samples sample = info.sample self.assertEqual(u'2015-05-27T00:22:00+0000', sample.time_stamp) self.assertEqual(1, sample.id) self.assertEqual('IOServer - SN2125D4A', sample.name) # Validate Memory self.assertIsNone(sample.mem) # Validate the Network self.assertIsNone(sample.network) # Validate the Storage self.assertIsNone(sample.storage)
def latest_stats(adapter, host_uuid, include_vio=True, second_latest=False): """Returns the latest PHYP and (optionally) VIOS statistics. :param adapter: The pypowervm adapter. :param host_uuid: The host system's UUID. :param include_vio: (Optional) Defaults to True. If set to false, the VIO metrics will always be returned as an empty list. :param second_latest: (Optional) Defaults to False. If set to True, it will pull the second to last metric for the return data. :return: datetime - When the metrics were pulled. :return: phyp_data - The PhypInfo object for the raw metrics. May be None if there are issues gathering the metrics. :return: vios_datas - The list of ViosInfo objects. May be empty if the metrics are unavailable or if the include_vio flag is False. Is a list as the system may have many Virtual I/O Servers. :return: lpar_metrics - The list of Lpar metrics received from querying IBM.Host Resource Manager via RMC. It may be empty is the metrics are unavailable or if the include_lpars flag is False. lpar_metrics are generally collected once every two minutes, as opposed to the other data which is collected every 30 seconds. """ ltm_metrics = query_ltm_feed(adapter, host_uuid) latest_phyp = _get_metric(ltm_metrics, 'phyp', second_latest=second_latest) # If there is no current metric, return None. if latest_phyp is None: return datetime.datetime.now(), None, None, None phyp_json = adapter.read_by_href(latest_phyp.link, xag=[]).body phyp_metric = phyp_mon.PhypInfo(phyp_json) # Now find the corresponding VIOS metrics for this. vios_ltms = [] for metric in ltm_metrics: # The VIOS metrics start with the key 'vios_' if not metric.category.startswith('vios_'): continue if metric.updated_datetime == latest_phyp.updated_datetime: vios_ltms.append(metric) if include_vio: vios_metrics = [ vios_mon.ViosInfo(adapter.read_by_href(x.link).body) for x in vios_ltms ] else: vios_metrics = [] # Now find the corresponding LPAR metrics for this. lpar_metrics = get_lpar_metrics(ltm_metrics, adapter, second_latest=second_latest) # Get the latest date, but if we're getting the second latest we know # it is 30 seconds old. The 30 seconds is the cadence that the REST API # collects the metric data. ret_date = datetime.datetime.now() if second_latest: ret_date = ret_date - datetime.timedelta(seconds=30) return ret_date, phyp_metric, vios_metrics, lpar_metrics
def test_parse(self): info = pcm_vios.ViosInfo(self.raw_json) self.assertIsNotNone(info) # Validate the info self.assertEqual('1.0.0', info.info.version) self.assertEqual('Raw', info.info.metric_type) self.assertEqual('LTM', info.info.monitoring_type) self.assertEqual('8247-22L*2125D4A', info.info.mtms) # Validate some samples sample = info.sample self.assertEqual(u'2015-05-27T00:22:00+0000', sample.time_stamp) self.assertEqual(1, sample.id) self.assertEqual('IOServer - SN2125D4A', sample.name) # Validate Memory self.assertEqual(1715, sample.mem.utilized_mem) # Validate the Network self.assertEqual(6, len(sample.network.adpts)) self.assertEqual(1, len(sample.network.seas)) phys_dev = sample.network.adpts[1] self.assertEqual('ent0', phys_dev.name) self.assertEqual('physical', phys_dev.type) self.assertEqual('U78CB.001.WZS007Y-P1-C10-T1', phys_dev.physical_location) self.assertEqual(1703083, phys_dev.received_packets) self.assertEqual(65801, phys_dev.sent_packets) self.assertEqual(0, phys_dev.dropped_packets) self.assertEqual(187004823, phys_dev.received_bytes) self.assertEqual(71198950, phys_dev.sent_bytes) # SEA validation sea = sample.network.seas[0] self.assertEqual('ent6', sea.name) self.assertEqual('sea', sea.type) self.assertEqual('U8247.22L.2125D4A-V1-C12-T1', sea.physical_location) self.assertEqual(0, sea.received_packets) self.assertEqual(0, sea.sent_packets) self.assertEqual(0, sea.dropped_packets) self.assertEqual(0, sea.received_bytes) self.assertEqual(0, sea.sent_bytes) self.assertEqual(['ent3', 'ent5'], sea.bridged_adpts) # Storage - FC Validation fc = sample.storage.fc_adpts[0] self.assertEqual('fcs0', fc.name) self.assertEqual('21000024ff649104', fc.wwpn) self.assertEqual('U78CB.001.WZS007Y-P1-C3-T1', fc.physical_location) self.assertEqual(0, fc.num_reads) self.assertEqual(0, fc.num_writes) self.assertEqual(0, fc.read_bytes) self.assertEqual(0, fc.write_bytes) self.assertEqual(8, fc.running_speed) # VFC Validation vfc = sample.storage.fc_adpts[1].ports[0] self.assertEqual("vfc1", vfc.name) self.assertEqual("21000024ff649159", vfc.wwpn) self.assertEqual(1234, vfc.num_reads) self.assertEqual(1235, vfc.num_writes) self.assertEqual(184184, vfc.read_bytes) self.assertEqual(138523, vfc.write_bytes) self.assertEqual(8, vfc.running_speed) self.assertEqual("U78CB.001.WZS007Y-P1-C3-T2000", vfc.physical_location) # Physical Adpt Validation padpt = sample.storage.phys_adpts[0] self.assertEqual('sissas0', padpt.name) self.assertEqual('U78CB.001.WZS007Y-P1-C14-T1', padpt.physical_location) self.assertEqual(1089692, padpt.num_reads) self.assertEqual(1288936, padpt.num_writes) self.assertEqual(557922304, padpt.read_bytes) self.assertEqual(659935232, padpt.write_bytes) self.assertEqual('sas', padpt.type) # Storage Virtual Adapter Validation vadpt = sample.storage.virt_adpts[0] self.assertEqual('vhost5', vadpt.name) self.assertEqual('U8247.22L.2125D4A-V1-C7', vadpt.physical_location) self.assertEqual(0, vadpt.num_reads) self.assertEqual(1, vadpt.num_writes) self.assertEqual(0, vadpt.read_bytes) self.assertEqual(512, vadpt.write_bytes) self.assertEqual('virtual', vadpt.type) # SSP Validation ssp = sample.storage.ssps[0] self.assertEqual('ssp1', ssp.name) self.assertEqual(["sissas0"], ssp.pool_disks) self.assertEqual(12346, ssp.num_reads) self.assertEqual(17542, ssp.num_writes) self.assertEqual(18352435, ssp.total_space) self.assertEqual(123452, ssp.used_space) self.assertEqual(123825, ssp.read_bytes) self.assertEqual(375322, ssp.write_bytes)
def test_parse_to_vm_metrics(self): """Verifies the parsing to LPAR metrics.""" phyp_resp = self._load(PHYP_DATA) phyp_data = pvm_mon_phyp.PhypInfo(phyp_resp) vios_resp = self._load(VIOS_DATA) vios_data = pvm_mon_vios.ViosInfo(vios_resp) lpar_resp = self._load(LPAR_DATA) lpar_data = pvm_mon_lpar.LparInfo(lpar_resp) metrics = pvm_t_mon.vm_metrics(phyp_data, [vios_data], lpar_data) self.assertIsNotNone(metrics) # In the test data, there are 5 LPARs total. self.assertEqual(5, len(metrics.keys())) # Validate a metric with live data good_vm = '42AD4FD4-DC64-4935-9E29-9B7C6F35AFCC' metric = metrics.get(good_vm) self.assertIsNotNone(metric) self.assertIsNotNone(metric.network) self.assertIsNotNone(metric.storage) self.assertIsNotNone(metric.processor) self.assertIsNotNone(metric.memory) # Memory validation self.assertEqual(20480, metric.memory.logical_mem) self.assertEqual(20480, metric.memory.backed_physical_mem) self.assertEqual(61, metric.memory.pct_real_mem_free) self.assertEqual(25, metric.memory.vm_pg_out_rate) # Processor validation self.assertEqual(0, metric.processor.pool_id) self.assertEqual('uncap', metric.processor.mode) self.assertEqual(4, metric.processor.virt_procs) self.assertEqual(.4, metric.processor.proc_units) # Network validation self.assertEqual(1, len(metric.network.cnas)) cna = metric.network.cnas[0] self.assertEqual(2227, cna.vlan_id) self.assertEqual(0, cna.vswitch_id) self.assertEqual('U8247.22L.2125D4A-V2-C2', cna.physical_location) self.assertEqual(10, cna.received_packets) self.assertEqual(100, cna.sent_packets) self.assertEqual(5, cna.dropped_packets) self.assertEqual(100, cna.sent_bytes) self.assertEqual(10000, cna.received_bytes) # Storage validation self.assertEqual(1, len(metric.storage.virt_adpts)) self.assertEqual(0, len(metric.storage.vfc_adpts)) vadpt = metric.storage.virt_adpts[0] self.assertEqual('virtual', vadpt.type) self.assertEqual('vhost0', vadpt.name) self.assertEqual('U8247.22L.2125D4A-V1-C1000', vadpt.physical_location) self.assertEqual(1074, vadpt.num_reads) self.assertEqual(1075, vadpt.num_writes) self.assertEqual(549888, vadpt.read_bytes) self.assertEqual(550400, vadpt.write_bytes) # Validate a metric for a system that was powered off. bad_vm = '3B0237F9-26F1-41C7-BE57-A08C9452AD9D' metric = metrics.get(bad_vm) self.assertIsNotNone(metric) self.assertIsNotNone(metric.processor) self.assertIsNotNone(metric.memory) # For powered off VM, the free memory is 100 percent. self.assertEqual(100, metric.memory.pct_real_mem_free) # For powered off VM, the page in/out rate is 0. self.assertEqual(0, metric.memory.vm_pg_out_rate) self.assertIsNone(metric.storage) self.assertIsNone(metric.network) # Take a VM which has entry in phyp data but not in PCM Lpar data. # Assert that it has been correctly parsed and memory metrics # are set to default values. vm_in_phyp_not_in_lpar_pcm = '66A2E886-D05D-42F4-87E0-C3BA02CF7C7E' metric = metrics.get(vm_in_phyp_not_in_lpar_pcm) self.assertIsNotNone(metric) self.assertIsNotNone(metric.processor) self.assertIsNotNone(metric.memory) self.assertEqual(.2, metric.processor.proc_units) self.assertEqual(0, metric.memory.pct_real_mem_free) self.assertEqual(-1, metric.memory.vm_pg_in_rate)
def test_parse_to_vm_metrics(self): """Verifies the parsing to LPAR metrics.""" phyp_resp = self._load(PHYP_DATA) phyp_data = pvm_mon_phyp.PhypInfo(phyp_resp) vios_resp = self._load(VIOS_DATA) vios_data = pvm_mon_vios.ViosInfo(vios_resp) metrics = pvm_t_mon.vm_metrics(phyp_data, [vios_data]) self.assertIsNotNone(metrics) # In the test data, there are 5 LPARs total. self.assertEqual(5, len(metrics.keys())) # Validate a metric with live data good_vm = '42AD4FD4-DC64-4935-9E29-9B7C6F35AFCC' metric = metrics.get(good_vm) self.assertIsNotNone(metric) self.assertIsNotNone(metric.network) self.assertIsNotNone(metric.storage) self.assertIsNotNone(metric.processor) self.assertIsNotNone(metric.memory) # Memory validation self.assertEqual(20480, metric.memory.logical_mem) self.assertEqual(20480, metric.memory.backed_physical_mem) # Processor validation self.assertEqual(0, metric.processor.pool_id) self.assertEqual('uncap', metric.processor.mode) self.assertEqual(4, metric.processor.virt_procs) self.assertEqual(.4, metric.processor.proc_units) # Network validation self.assertEqual(1, len(metric.network.cnas)) cna = metric.network.cnas[0] self.assertEqual(2227, cna.vlan_id) self.assertEqual(0, cna.vswitch_id) self.assertEqual('U8247.22L.2125D4A-V2-C2', cna.physical_location) self.assertEqual(10, cna.received_packets) self.assertEqual(100, cna.sent_packets) self.assertEqual(5, cna.dropped_packets) self.assertEqual(100, cna.sent_bytes) self.assertEqual(10000, cna.received_bytes) # Storage validation self.assertEqual(1, len(metric.storage.virt_adpts)) self.assertEqual(0, len(metric.storage.vfc_adpts)) vadpt = metric.storage.virt_adpts[0] self.assertEqual('virtual', vadpt.type) self.assertEqual('vhost0', vadpt.name) self.assertEqual('U8247.22L.2125D4A-V1-C1000', vadpt.physical_location) self.assertEqual(1074, vadpt.num_reads) self.assertEqual(1075, vadpt.num_writes) self.assertEqual(549888, vadpt.read_bytes) self.assertEqual(550400, vadpt.write_bytes) # Validate a metric for a system that was powered off. bad_vm = '3B0237F9-26F1-41C7-BE57-A08C9452AD9D' metric = metrics.get(bad_vm) self.assertIsNotNone(metric) self.assertIsNotNone(metric.processor) self.assertIsNotNone(metric.memory) self.assertIsNone(metric.storage) self.assertIsNone(metric.network)