From f51b20e21f21cb6a854baad456604478e41669b3 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Wed, 3 Jul 2013 13:11:45 -0400 Subject: [PATCH] Update compute CPU pollster to use cache Use the pollster cache to store the CPU statistics for an instance. Eventually the single pollster will be broken up into separate pollsters that all use the cache. blueprint one-meter-per-plugin Change-Id: Iada02930867c09d05684ba0acea728d0d1cf06ae Signed-off-by: Doug Hellmann --- ceilometer/compute/pollsters.py | 18 +++++++++++++++--- tests/compute/test_pollsters.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/ceilometer/compute/pollsters.py b/ceilometer/compute/pollsters.py index 40ab7a733..ae185a281 100644 --- a/ceilometer/compute/pollsters.py +++ b/ceilometer/compute/pollsters.py @@ -169,7 +169,7 @@ class CPUPollster(plugin.ComputePollster): utilization_map = {} - def get_cpu_util(self, instance, cpu_info): + def _get_cpu_util(self, instance, cpu_info): prev_times = self.utilization_map.get(instance.id) self.utilization_map[instance.id] = (cpu_info.time, datetime.datetime.now()) @@ -186,6 +186,14 @@ class CPUPollster(plugin.ComputePollster): cpu_util = 100 * cores_fraction * time_used / elapsed return cpu_util + CACHE_KEY_CPU = 'cpu' + + def _get_cpu_info(self, inspector, instance_name, cache): + i_cache = cache.setdefault(self.CACHE_KEY_CPU, {}) + if instance_name not in i_cache: + i_cache[instance_name] = inspector.inspect_cpus(instance_name) + return i_cache[instance_name] + @staticmethod def get_counter_names(): return ['cpu', 'cpu_util'] @@ -194,10 +202,14 @@ class CPUPollster(plugin.ComputePollster): self.LOG.info('checking instance %s', instance.id) instance_name = _instance_name(instance) try: - cpu_info = manager.inspector.inspect_cpus(instance_name) + cpu_info = self._get_cpu_info( + manager.inspector, + instance_name, + cache, + ) self.LOG.info("CPUTIME USAGE: %s %d", instance.__dict__, cpu_info.time) - cpu_util = self.get_cpu_util(instance, cpu_info) + cpu_util = self._get_cpu_util(instance, cpu_info) self.LOG.info("CPU UTILIZATION %%: %s %0.2f", instance.__dict__, cpu_util) # FIXME(eglynn): once we have a way of configuring which measures diff --git a/tests/compute/test_pollsters.py b/tests/compute/test_pollsters.py index bac97258c..1e22a7a8d 100644 --- a/tests/compute/test_pollsters.py +++ b/tests/compute/test_pollsters.py @@ -240,7 +240,8 @@ class TestCPUPollster(TestPollsterBase): pollster = pollsters.CPUPollster() def _verify_cpu_metering(zero, expected_time): - counters = list(pollster.get_counters(mgr, {}, self.instance)) + cache = {} + counters = list(pollster.get_counters(mgr, cache, self.instance)) self.assertEquals(len(counters), 2) self.assertEqual(set([c.name for c in counters]), set(pollster.get_counter_names())) @@ -249,9 +250,37 @@ class TestCPUPollster(TestPollsterBase): counters[0].volume > 0.0) assert counters[1].name == 'cpu' assert counters[1].volume == expected_time + assert pollster.CACHE_KEY_CPU in cache + assert self.instance.name in cache[pollster.CACHE_KEY_CPU] # ensure elapsed time between polling cycles is non-zero time.sleep(0.001) _verify_cpu_metering(True, 1 * (10 ** 6)) _verify_cpu_metering(False, 3 * (10 ** 6)) _verify_cpu_metering(False, 2 * (10 ** 6)) + + @mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock()) + def test_get_counters_cache(self): + # self.inspector.inspect_cpus(self.instance.name).AndReturn( + # virt_inspector.CPUStats(time=1 * (10 ** 6), number=2)) + # self.inspector.inspect_cpus(self.instance.name).AndReturn( + # virt_inspector.CPUStats(time=3 * (10 ** 6), number=2)) + # # cpu_time resets on instance restart + # self.inspector.inspect_cpus(self.instance.name).AndReturn( + # virt_inspector.CPUStats(time=2 * (10 ** 6), number=2)) + self.mox.ReplayAll() + + mgr = manager.AgentManager() + pollster = pollsters.CPUPollster() + + cache = { + pollster.CACHE_KEY_CPU: { + self.instance.name: virt_inspector.CPUStats( + time=10 ** 6, + number=2, + ), + }, + } + counters = list(pollster.get_counters(mgr, cache, self.instance)) + self.assertEquals(len(counters), 2) + self.assertEquals(counters[1].volume, 10 ** 6)