Allow monitor plugins to set own metric object
The values reported by a monitor depends on the type of value which will not be uniform for all the monitors. For example, the memory bandwidth monitor will return a dict of ints while the cpu monitor returns a normal int value. The monitor metric objects offer different fields to be set depending on the monitor in question. This patchset allows the monitors to decide what metric field it would like to populate as over a general implementation of creating the monitor metric object inside the base module. This would also help in exchanging versioned objects between the monitors and the compute drivers. Eventually this work will lead up to making the metrics.update notification as versioned. Related to blueprint memory-bw Co-Authored-By: Ahilan Rajadeva <rajadeva@us.ibm.com> Change-Id: Ieaf3d44bbe73e71ad877199bbbc779afa4218b51
This commit is contained in:
parent
a074c661e4
commit
2a53063679
@ -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):
|
||||
|
@ -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 = {}
|
||||
|
@ -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"),
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
10
releasenotes/notes/bp-memory-bw-4ceb971cfe1a2fd0.yaml
Normal file
10
releasenotes/notes/bp-memory-bw-4ceb971cfe1a2fd0.yaml
Normal file
@ -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.
|
Loading…
x
Reference in New Issue
Block a user