diff --git a/nova/compute/monitors/base.py b/nova/compute/monitors/base.py index 44946c54cd38..b4ad686ea399 100644 --- a/nova/compute/monitors/base.py +++ b/nova/compute/monitors/base.py @@ -14,7 +14,6 @@ import abc import six -from nova import objects from nova.objects import fields @@ -44,9 +43,10 @@ class MonitorBase(object): raise NotImplementedError('get_metric_names') @abc.abstractmethod - def get_metrics(self): - """Returns a list of tuples containing information for all metrics - tracked by the monitor. + def populate_metrics(self, metric_list): + """Monitors are responsible for populating this metric_list object + with nova.objects.MonitorMetric objects with values collected via + the respective compute drivers. Note that if the monitor class is responsible for tracking a *related* set of metrics -- e.g. a set of percentages of CPU time allocated to @@ -54,26 +54,9 @@ class MonitorBase(object): implementation to do a single sampling call to the underlying monitor to ensure that related metric values make logical sense. - :returns: list of (metric_name, value, timestamp) tuples + :param metric_list: A mutable reference of the metric list object """ - raise NotImplementedError('get_metrics') - - def add_metrics_to_list(self, metrics_list): - """Adds metric objects to a supplied list object. - - :param metric_list: nova.objects.MonitorMetricList that the monitor - plugin should append nova.objects.MonitorMetric - objects to. - """ - metric_data = self.get_metrics() - metrics = [] - for (name, value, timestamp) in metric_data: - metric = objects.MonitorMetric(name=name, - value=value, - timestamp=timestamp, - source=self.source) - metrics.append(metric) - metrics_list.objects.extend(metrics) + raise NotImplementedError('populate_metrics') class CPUMonitorBase(MonitorBase): diff --git a/nova/compute/monitors/cpu/virt_driver.py b/nova/compute/monitors/cpu/virt_driver.py index ef7a01b76a0b..604423e2b353 100644 --- a/nova/compute/monitors/cpu/virt_driver.py +++ b/nova/compute/monitors/cpu/virt_driver.py @@ -24,6 +24,7 @@ from nova.compute.monitors import base import nova.conf from nova import exception from nova.i18n import _LE +from nova import objects CONF = nova.conf.CONF LOG = logging.getLogger(__name__) @@ -39,12 +40,15 @@ class Monitor(base.CPUMonitorBase): self._data = {} self._cpu_stats = {} - def get_metrics(self): - metrics = [] + def populate_metrics(self, metric_list): self._update_data() for name in self.get_metric_names(): - metrics.append((name, self._data[name], self._data["timestamp"])) - return metrics + metric_object = objects.MonitorMetric() + metric_object.name = name + metric_object.value = self._data[name] + metric_object.timestamp = self._data["timestamp"] + metric_object.source = self.source + metric_list.objects.append(metric_object) def _update_data(self): self._data = {} diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py index 3c28a56e5c2f..b669fa92f9b9 100644 --- a/nova/compute/resource_tracker.py +++ b/nova/compute/resource_tracker.py @@ -471,7 +471,7 @@ class ResourceTracker(object): metrics_info = {} for monitor in self.monitors: try: - monitor.add_metrics_to_list(metrics) + monitor.populate_metrics(metrics) except Exception as exc: LOG.warning(_LW("Cannot get the metrics from %(mon)s; " "error: %(exc)s"), diff --git a/nova/tests/unit/compute/monitors/cpu/test_virt_driver.py b/nova/tests/unit/compute/monitors/cpu/test_virt_driver.py index 992ffd05f9cc..aed34ea30c87 100644 --- a/nova/tests/unit/compute/monitors/cpu/test_virt_driver.py +++ b/nova/tests/unit/compute/monitors/cpu/test_virt_driver.py @@ -52,10 +52,10 @@ class VirtDriverCPUMonitorTestCase(test.NoDBTestCase): self.assertIn("cpu.iowait.percent", names) self.assertIn("cpu.percent", names) - def test_get_metrics(self): + def test_populate_metrics(self): metrics = objects.MonitorMetricList() monitor = virt_driver.Monitor(FakeResourceTracker()) - monitor.add_metrics_to_list(metrics) + monitor.populate_metrics(metrics) names = monitor.get_metric_names() for metric in metrics.objects: self.assertIn(metric.name, names) @@ -82,5 +82,5 @@ class VirtDriverCPUMonitorTestCase(test.NoDBTestCase): monitor = virt_driver.Monitor(FakeResourceTracker()) with mock.patch.object(FakeDriver, 'get_host_cpu_stats') as mocked: - monitor.add_metrics_to_list(metrics) + monitor.populate_metrics(metrics) mocked.assert_called_once_with() diff --git a/nova/tests/unit/compute/test_resource_tracker.py b/nova/tests/unit/compute/test_resource_tracker.py index a1e970dde4fb..22eb55a99728 100644 --- a/nova/tests/unit/compute/test_resource_tracker.py +++ b/nova/tests/unit/compute/test_resource_tracker.py @@ -638,7 +638,7 @@ class ComputeMonitorTestCase(BaseTestCase): @mock.patch.object(resource_tracker.LOG, 'warning') def test_get_host_metrics_exception(self, mock_LOG_warning): monitor = mock.MagicMock() - monitor.add_metrics_to_list.side_effect = Exception + monitor.populate_metrics.side_effect = Exception self.tracker.monitors = [monitor] metrics = self.tracker._get_host_metrics(self.context, self.node_name) @@ -658,8 +658,13 @@ class ComputeMonitorTestCase(BaseTestCase): def get_metric_names(self): return set(["cpu.frequency"]) - def get_metrics(self): - return [("cpu.frequency", 100, self.NOW_TS)] + def populate_metrics(self, monitor_list): + metric_object = objects.MonitorMetric() + metric_object.name = 'cpu.frequency' + metric_object.value = 100 + metric_object.timestamp = self.NOW_TS + metric_object.source = self.source + monitor_list.objects.append(metric_object) self.tracker.monitors = [FakeCPUMonitor(None)] mock_notifier = mock.Mock() diff --git a/releasenotes/notes/bp-memory-bw-4ceb971cfe1a2fd0.yaml b/releasenotes/notes/bp-memory-bw-4ceb971cfe1a2fd0.yaml new file mode 100644 index 000000000000..05cd3cc5cbe1 --- /dev/null +++ b/releasenotes/notes/bp-memory-bw-4ceb971cfe1a2fd0.yaml @@ -0,0 +1,10 @@ +--- +upgrade: + - The get_metrics API has been replaced by + populate_metrics in nova.compute.monitors.base + module. This change is introduced to allow each + monitor plugin to have the flexibility of setting + it's own metric value types. The in-tree metrics + plugins are modified as a part of this change. + However, the out-of-tree plugins would have to + adapt to the new API in order to work with nova.