diff --git a/ceilometer/compute/notifications/__init__.py b/ceilometer/compute/notifications/__init__.py new file mode 100644 index 00000000..bb258d42 --- /dev/null +++ b/ceilometer/compute/notifications/__init__.py @@ -0,0 +1,45 @@ +# -*- encoding: utf-8 -*- +# +# Copyright © 2013 Intel +# +# Author: Shuangtai Tian +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo.config import cfg + +from ceilometer import plugin + + +OPTS = [ + cfg.StrOpt('nova_control_exchange', + default='nova', + help="Exchange name for Nova notifications"), +] + + +cfg.CONF.register_opts(OPTS) + + +class ComputeNotificationBase(plugin.NotificationBase): + @staticmethod + def get_exchange_topics(conf): + """Return a sequence of ExchangeTopics defining the exchange and + topics to be connected for this plugin. + """ + return [ + plugin.ExchangeTopics( + exchange=conf.nova_control_exchange, + topics=set(topic + ".info" + for topic in conf.notification_topics)), + ] diff --git a/ceilometer/compute/notifications/cpu.py b/ceilometer/compute/notifications/cpu.py new file mode 100644 index 00000000..c5ec9871 --- /dev/null +++ b/ceilometer/compute/notifications/cpu.py @@ -0,0 +1,140 @@ +# -*- encoding: utf-8 -*- +# +# Copyright © 2013 Intel +# +# Author: Shuangtai Tian +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +"""Converters for producing compute CPU sample messages from notification +events. +""" + +from ceilometer.compute import notifications +from ceilometer.openstack.common.gettextutils import _ # noqa +from ceilometer.openstack.common import log +from ceilometer.openstack.common import timeutils +from ceilometer import sample + +LOG = log.getLogger(__name__) + + +class ComputeMetricsNotificationBase(notifications.ComputeNotificationBase): + """Convert compute.metrics.update notifications into Samples + """ + event_types = ['compute.metrics.update'] + metric = None + sample_type = None + unit = None + + @staticmethod + def _get_sample(message, name): + try: + for metric in message['payload']['metrics']: + if name == metric['name']: + info = {} + info['payload'] = metric + info['event_type'] = message['event_type'] + info['publisher_id'] = message['publisher_id'] + info['resource_id'] = '%s_%s' % ( + message['payload']['host'], + message['payload']['nodename']) + info['timestamp'] = str(timeutils.parse_strtime( + metric['timestamp'])) + return info + except Exception as err: + LOG.warning(_('An error occurred while building %(m)s ' + 'sample: %(e)s') % {'m': name, 'e': err}) + + def process_notification(self, message): + info = self._get_sample(message, self.metric) + if info: + yield sample.Sample.from_notification( + name='compute.node.%s' % self.metric, + type=self.sample_type, + unit=self.unit, + volume=(info['payload']['value'] * 100 if self.unit == '%' + else info['payload']['value']), + user_id=None, + project_id=None, + resource_id=info['resource_id'], + message=info) + + +class CpuFrequency(ComputeMetricsNotificationBase): + """Handle CPU current frequency message.""" + metric = 'cpu.frequency' + sample_type = sample.TYPE_GAUGE, + unit = 'MHz' + + +class CpuUserTime(ComputeMetricsNotificationBase): + """Handle CPU user mode time message.""" + metric = 'cpu.user.time' + sample_type = sample.TYPE_CUMULATIVE, + unit = 'ns' + + +class CpuKernelTime(ComputeMetricsNotificationBase): + """Handle CPU kernel time message.""" + metric = 'cpu.kernel.time' + unit = 'ns' + sample_type = sample.TYPE_CUMULATIVE, + + +class CpuIdleTime(ComputeMetricsNotificationBase): + """Handle CPU idle time message.""" + metric = 'cpu.idle.time' + unit = 'ns' + sample_type = sample.TYPE_CUMULATIVE, + + +class CpuIowaitTime(ComputeMetricsNotificationBase): + """Handle CPU I/O wait time message.""" + metric = 'cpu.iowait.time' + unit = 'ns' + sample_type = sample.TYPE_CUMULATIVE, + + +class CpuKernelPercent(ComputeMetricsNotificationBase): + """Handle CPU kernel percentage message.""" + metric = 'cpu.kernel.percent' + unit = '%' + sample_type = sample.TYPE_GAUGE, + + +class CpuIdlePercent(ComputeMetricsNotificationBase): + """Handle CPU idle percentage message.""" + metric = 'cpu.idle.percent' + unit = '%' + sample_type = sample.TYPE_GAUGE, + + +class CpuUserPercent(ComputeMetricsNotificationBase): + """Handle CPU user mode percentage message.""" + metric = 'cpu.user.percent' + unit = '%' + sample_type = sample.TYPE_GAUGE, + + +class CpuIowaitPercent(ComputeMetricsNotificationBase): + """Handle CPU I/O wait percentage message.""" + metric = 'cpu.iowait.percent' + unit = '%' + sample_type = sample.TYPE_GAUGE, + + +class CpuPercent(ComputeMetricsNotificationBase): + """Handle generic CPU utilization message.""" + metric = 'cpu.percent' + unit = '%' + sample_type = sample.TYPE_GAUGE, diff --git a/ceilometer/compute/notifications.py b/ceilometer/compute/notifications/instance.py similarity index 86% rename from ceilometer/compute/notifications.py rename to ceilometer/compute/notifications/instance.py index 405ea967..2887dd6f 100644 --- a/ceilometer/compute/notifications.py +++ b/ceilometer/compute/notifications/instance.py @@ -20,37 +20,11 @@ """Converters for producing compute sample messages from notification events. """ -from oslo.config import cfg - -from ceilometer import plugin +from ceilometer.compute import notifications from ceilometer import sample -OPTS = [ - cfg.StrOpt('nova_control_exchange', - default='nova', - help="Exchange name for Nova notifications"), -] - - -cfg.CONF.register_opts(OPTS) - - -class ComputeNotificationBase(plugin.NotificationBase): - @staticmethod - def get_exchange_topics(conf): - """Return a sequence of ExchangeTopics defining the exchange and - topics to be connected for this plugin. - """ - return [ - plugin.ExchangeTopics( - exchange=conf.nova_control_exchange, - topics=set(topic + ".info" - for topic in conf.notification_topics)), - ] - - -class InstanceScheduled(ComputeNotificationBase): +class InstanceScheduled(notifications.ComputeNotificationBase): event_types = ['scheduler.run_instance.scheduled'] def process_notification(self, message): @@ -67,7 +41,7 @@ class InstanceScheduled(ComputeNotificationBase): message=message) -class ComputeInstanceNotificationBase(ComputeNotificationBase): +class ComputeInstanceNotificationBase(notifications.ComputeNotificationBase): """Convert compute.instance.* notifications into Samples """ event_types = ['compute.instance.*'] diff --git a/ceilometer/tests/compute/notifications/__init__.py b/ceilometer/tests/compute/notifications/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ceilometer/tests/compute/notifications/test_cpu.py b/ceilometer/tests/compute/notifications/test_cpu.py new file mode 100644 index 00000000..63fe07ff --- /dev/null +++ b/ceilometer/tests/compute/notifications/test_cpu.py @@ -0,0 +1,159 @@ +# -*- encoding: utf-8 -*- +# +# Copyright © 2013 Intel +# +# Author: Shuangtai Tian +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +"""Tests for converters for producing compute counter messages from +notification events. +""" + +import copy + +from ceilometer.compute.notifications import cpu +from ceilometer.openstack.common import test + + +METRICS_UPDATE = { + u'_context_request_id': u'req-a8bfa89b-d28b-4b95-9e4b-7d7875275650', + u'_context_quota_class': None, + u'event_type': u'compute.metrics.update', + u'_context_service_catalog': [], + u'_context_auth_token': None, + u'_context_user_id': None, + u'payload': { + u'metrics': [ + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.frequency', 'value': 1600, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.user.time', 'value': 17421440000000L, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.kernel.time', 'value': 7852600000000L, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.idle.time', 'value': 1307374400000000L, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.iowait.time', 'value': 11697470000000L, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.user.percent', 'value': 0.012959045637294348, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.kernel.percent', 'value': 0.005841204961898534, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.idle.percent', 'value': 0.9724985141658965, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.iowait.percent', 'value': 0.008701235234910634, + 'source': 'libvirt.LibvirtDriver'}, + {'timestamp': u'2013-07-29T06:51:34.472416', + 'name': 'cpu.percent', 'value': 0.027501485834103515, + 'source': 'libvirt.LibvirtDriver'}], + u'nodename': u'tianst.sh.intel.com', + u'host': u'tianst', + u'host_id': u'10.0.1.1'}, + u'priority': u'INFO', + u'_context_is_admin': True, + u'_context_user': None, + u'publisher_id': u'compute.tianst.sh.intel.com', + u'message_id': u'6eccedba-120e-4db8-9735-2ad5f061e5ee', + u'_context_remote_address': None, + u'_context_roles': [], + u'timestamp': u'2013-07-29 06:51:34.474815', + u'_context_timestamp': u'2013-07-29T06:51:34.348091', + u'_unique_id': u'0ee26117077648e18d88ac76e28a72e2', + u'_context_project_name': None, + u'_context_read_deleted': u'no', + u'_context_tenant': None, + u'_context_instance_lock_checked': False, + u'_context_project_id': None, + u'_context_user_name': None +} + +RES_ID = '%s_%s' % (METRICS_UPDATE['payload']['host'], + METRICS_UPDATE['payload']['nodename']) + + +class TestMetricsNotifications(test.BaseTestCase): + def _process_notification(self, ic): + self.assertIn(METRICS_UPDATE['event_type'], + ic.event_types) + samples = list(ic.process_notification(METRICS_UPDATE)) + self.assertEqual(samples[0].resource_id, RES_ID) + return samples[0] + + def test_compute_metrics(self): + ERROR_METRICS = copy.copy(METRICS_UPDATE) + ERROR_METRICS['payload'] = {"metric_err": []} + ic = cpu.CpuFrequency() + info = ic._get_sample(METRICS_UPDATE, 'cpu.frequency') + info_none = ic._get_sample(METRICS_UPDATE, 'abc.efg') + info_error = ic._get_sample(ERROR_METRICS, 'cpu.frequency') + self.assertEqual(info['payload']['name'], 'cpu.frequency') + self.assertEqual(info_none, None) + self.assertEqual(info_error, None) + + def test_compute_cpu_frequency(self): + c = self._process_notification(cpu.CpuFrequency()) + self.assertEqual(c.name, 'compute.node.cpu.frequency') + self.assertEqual(c.volume, 1600) + + def test_compute_cpu_user_time(self): + c = self._process_notification(cpu.CpuUserTime()) + self.assertEqual(c.name, 'compute.node.cpu.user.time') + self.assertEqual(c.volume, 17421440000000L) + + def test_compute_cpu_kernel_time(self): + c = self._process_notification(cpu.CpuKernelTime()) + self.assertEqual(c.name, 'compute.node.cpu.kernel.time') + self.assertEqual(c.volume, 7852600000000L) + + def test_compute_cpu_idle_time(self): + c = self._process_notification(cpu.CpuIdleTime()) + self.assertEqual(c.name, 'compute.node.cpu.idle.time') + self.assertEqual(c.volume, 1307374400000000L) + + def test_compute_cpu_iowait_time(self): + c = self._process_notification(cpu.CpuIowaitTime()) + self.assertEqual(c.name, 'compute.node.cpu.iowait.time') + self.assertEqual(c.volume, 11697470000000L) + + def test_compute_cpu_kernel_percent(self): + c = self._process_notification(cpu.CpuKernelPercent()) + self.assertEqual(c.name, 'compute.node.cpu.kernel.percent') + self.assertEqual(c.volume, 0.5841204961898534) + + def test_compute_cpu_idle_percent(self): + c = self._process_notification(cpu.CpuIdlePercent()) + self.assertEqual(c.name, 'compute.node.cpu.idle.percent') + self.assertEqual(c.volume, 97.24985141658965) + + def test_compute_cpu_user_percent(self): + c = self._process_notification(cpu.CpuUserPercent()) + self.assertEqual(c.name, 'compute.node.cpu.user.percent') + self.assertEqual(c.volume, 1.2959045637294348) + + def test_compute_cpu_iowait_percent(self): + c = self._process_notification(cpu.CpuIowaitPercent()) + self.assertEqual(c.name, 'compute.node.cpu.iowait.percent') + self.assertEqual(c.volume, 0.8701235234910634) + + def test_compute_cpu_percent(self): + c = self._process_notification(cpu.CpuPercent()) + self.assertEqual(c.name, 'compute.node.cpu.percent') + self.assertEqual(c.volume, 2.7501485834103515) diff --git a/ceilometer/tests/compute/test_notifications.py b/ceilometer/tests/compute/notifications/test_instance.py similarity index 96% rename from ceilometer/tests/compute/test_notifications.py rename to ceilometer/tests/compute/notifications/test_instance.py index bc4574a4..10d61d36 100644 --- a/ceilometer/tests/compute/test_notifications.py +++ b/ceilometer/tests/compute/notifications/test_instance.py @@ -21,7 +21,7 @@ notification events. """ -from ceilometer.compute import notifications +from ceilometer.compute.notifications import instance from ceilometer.openstack.common import test from ceilometer import sample @@ -401,7 +401,7 @@ INSTANCE_SCHEDULED = { class TestNotifications(test.BaseTestCase): def test_process_notification(self): - info = list(notifications.Instance().process_notification( + info = list(instance.Instance().process_notification( INSTANCE_CREATE_END ))[0] for name, actual, expected in [ @@ -425,42 +425,42 @@ class TestNotifications(test.BaseTestCase): return filter(lambda counter: counter.name == name, counters)[0] def test_instance_create_instance(self): - ic = notifications.Instance() + ic = instance.Instance() counters = list(ic.process_notification(INSTANCE_CREATE_END)) self.assertEqual(len(counters), 1) c = counters[0] self.assertEqual(c.volume, 1) def test_instance_create_flavor(self): - ic = notifications.InstanceFlavor() + ic = instance.InstanceFlavor() counters = list(ic.process_notification(INSTANCE_CREATE_END)) self.assertEqual(len(counters), 1) c = counters[0] self.assertEqual(c.volume, 1) def test_instance_create_memory(self): - ic = notifications.Memory() + ic = instance.Memory() counters = list(ic.process_notification(INSTANCE_CREATE_END)) self.assertEqual(len(counters), 1) c = counters[0] self.assertEqual(c.volume, INSTANCE_CREATE_END['payload']['memory_mb']) def test_instance_create_vcpus(self): - ic = notifications.VCpus() + ic = instance.VCpus() counters = list(ic.process_notification(INSTANCE_CREATE_END)) self.assertEqual(len(counters), 1) c = counters[0] self.assertEqual(c.volume, INSTANCE_CREATE_END['payload']['vcpus']) def test_instance_create_root_disk_size(self): - ic = notifications.RootDiskSize() + ic = instance.RootDiskSize() counters = list(ic.process_notification(INSTANCE_CREATE_END)) self.assertEqual(len(counters), 1) c = counters[0] self.assertEqual(c.volume, INSTANCE_CREATE_END['payload']['root_gb']) def test_instance_create_ephemeral_disk_size(self): - ic = notifications.EphemeralDiskSize() + ic = instance.EphemeralDiskSize() counters = list(ic.process_notification(INSTANCE_CREATE_END)) self.assertEqual(len(counters), 1) c = counters[0] @@ -468,34 +468,34 @@ class TestNotifications(test.BaseTestCase): INSTANCE_CREATE_END['payload']['ephemeral_gb']) def test_instance_exists_instance(self): - ic = notifications.Instance() + ic = instance.Instance() counters = list(ic.process_notification(INSTANCE_EXISTS)) self.assertEqual(len(counters), 1) def test_instance_exists_flavor(self): - ic = notifications.Instance() + ic = instance.Instance() counters = list(ic.process_notification(INSTANCE_EXISTS)) self.assertEqual(len(counters), 1) def test_instance_delete_instance(self): - ic = notifications.Instance() + ic = instance.Instance() counters = list(ic.process_notification(INSTANCE_DELETE_START)) self.assertEqual(len(counters), 1) def test_instance_delete_flavor(self): - ic = notifications.Instance() + ic = instance.Instance() counters = list(ic.process_notification(INSTANCE_DELETE_START)) self.assertEqual(len(counters), 1) def test_instance_finish_resize_instance(self): - ic = notifications.Instance() + ic = instance.Instance() counters = list(ic.process_notification(INSTANCE_FINISH_RESIZE_END)) self.assertEqual(len(counters), 1) c = counters[0] self.assertEqual(c.volume, 1) def test_instance_finish_resize_flavor(self): - ic = notifications.InstanceFlavor() + ic = instance.InstanceFlavor() counters = list(ic.process_notification(INSTANCE_FINISH_RESIZE_END)) self.assertEqual(len(counters), 1) c = counters[0] @@ -503,7 +503,7 @@ class TestNotifications(test.BaseTestCase): self.assertEqual(c.name, 'instance:m1.small') def test_instance_finish_resize_memory(self): - ic = notifications.Memory() + ic = instance.Memory() counters = list(ic.process_notification(INSTANCE_FINISH_RESIZE_END)) self.assertEqual(len(counters), 1) c = counters[0] @@ -511,7 +511,7 @@ class TestNotifications(test.BaseTestCase): INSTANCE_FINISH_RESIZE_END['payload']['memory_mb']) def test_instance_finish_resize_vcpus(self): - ic = notifications.VCpus() + ic = instance.VCpus() counters = list(ic.process_notification(INSTANCE_FINISH_RESIZE_END)) self.assertEqual(len(counters), 1) c = counters[0] @@ -519,14 +519,14 @@ class TestNotifications(test.BaseTestCase): INSTANCE_FINISH_RESIZE_END['payload']['vcpus']) def test_instance_resize_finish_instance(self): - ic = notifications.Instance() + ic = instance.Instance() counters = list(ic.process_notification(INSTANCE_FINISH_RESIZE_END)) self.assertEqual(len(counters), 1) c = counters[0] self.assertEqual(c.volume, 1) def test_instance_resize_finish_flavor(self): - ic = notifications.InstanceFlavor() + ic = instance.InstanceFlavor() counters = list(ic.process_notification(INSTANCE_RESIZE_REVERT_END)) self.assertEqual(len(counters), 1) c = counters[0] @@ -534,7 +534,7 @@ class TestNotifications(test.BaseTestCase): self.assertEqual(c.name, 'instance:m1.tiny') def test_instance_resize_finish_memory(self): - ic = notifications.Memory() + ic = instance.Memory() counters = list(ic.process_notification(INSTANCE_RESIZE_REVERT_END)) self.assertEqual(len(counters), 1) c = counters[0] @@ -542,7 +542,7 @@ class TestNotifications(test.BaseTestCase): INSTANCE_RESIZE_REVERT_END['payload']['memory_mb']) def test_instance_resize_finish_vcpus(self): - ic = notifications.VCpus() + ic = instance.VCpus() counters = list(ic.process_notification(INSTANCE_RESIZE_REVERT_END)) self.assertEqual(len(counters), 1) c = counters[0] @@ -550,14 +550,14 @@ class TestNotifications(test.BaseTestCase): INSTANCE_RESIZE_REVERT_END['payload']['vcpus']) def test_instance_delete_samples(self): - ic = notifications.InstanceDelete() + ic = instance.InstanceDelete() counters = list(ic.process_notification(INSTANCE_DELETE_SAMPLES)) self.assertEqual(len(counters), 2) names = [c.name for c in counters] self.assertEqual(names, ['sample-name1', 'sample-name2']) def test_instance_scheduled(self): - ic = notifications.InstanceScheduled() + ic = instance.InstanceScheduled() self.assertIn(INSTANCE_SCHEDULED['event_type'], ic.event_types) diff --git a/ceilometer/tests/test_notification.py b/ceilometer/tests/test_notification.py index 81da5759..3cca8841 100644 --- a/ceilometer/tests/test_notification.py +++ b/ceilometer/tests/test_notification.py @@ -23,7 +23,7 @@ import mock from stevedore import extension from stevedore.tests import manager as test_manager -from ceilometer.compute import notifications +from ceilometer.compute.notifications import instance from ceilometer import notification from ceilometer.openstack.common.fixture import config from ceilometer.openstack.common import timeutils @@ -101,7 +101,7 @@ class TestNotification(tests_base.BaseTestCase): [extension.Extension('test', None, None, - notifications.Instance(), + instance.Instance(), ), ]) self.srv.process_notification(TEST_NOTICE) diff --git a/setup.cfg b/setup.cfg index a7518dfe..1a65b1d6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,14 +29,24 @@ packages = [entry_points] ceilometer.notification = - instance = ceilometer.compute.notifications:Instance - instance_flavor = ceilometer.compute.notifications:InstanceFlavor - instance_delete = ceilometer.compute.notifications:InstanceDelete - instance_scheduled = ceilometer.compute.notifications:InstanceScheduled - memory = ceilometer.compute.notifications:Memory - vcpus = ceilometer.compute.notifications:VCpus - disk_root_size = ceilometer.compute.notifications:RootDiskSize - disk_ephemeral_size = ceilometer.compute.notifications:EphemeralDiskSize + instance = ceilometer.compute.notifications.instance:Instance + instance_flavor = ceilometer.compute.notifications.instance:InstanceFlavor + instance_delete = ceilometer.compute.notifications.instance:InstanceDelete + instance_scheduled = ceilometer.compute.notifications.instance:InstanceScheduled + memory = ceilometer.compute.notifications.instance:Memory + vcpus = ceilometer.compute.notifications.instance:VCpus + disk_root_size = ceilometer.compute.notifications.instance:RootDiskSize + disk_ephemeral_size = ceilometer.compute.notifications.instance:EphemeralDiskSize + cpu_frequency = ceilometer.compute.notifications.cpu:CpuFrequency + cpu_user_time = ceilometer.compute.notifications.cpu:CpuUserTime + cpu_kernel_time = ceilometer.compute.notifications.cpu:CpuKernelTime + cpu_idle_time = ceilometer.compute.notifications.cpu:CpuIdleTime + cpu_iowait_time = ceilometer.compute.notifications.cpu:CpuIowaitTime + cpu_kernel_percent = ceilometer.compute.notifications.cpu:CpuKernelPercent + cpu_idle_percent = ceilometer.compute.notifications.cpu:CpuIdlePercent + cpu_user_percent = ceilometer.compute.notifications.cpu:CpuUserPercent + cpu_iowait_percent = ceilometer.compute.notifications.cpu:CpuIowaitPercent + cpu_percent = ceilometer.compute.notifications.cpu:CpuPercent volume = ceilometer.volume.notifications:Volume volume_size = ceilometer.volume.notifications:VolumeSize image_crud = ceilometer.image.notifications:ImageCRUD