Files
deb-nova/nova/compute/monitors/cpu/virt_driver.py
Sudipta Biswas 2a53063679 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
2016-06-27 14:38:32 +05:30

103 lines
4.1 KiB
Python

# Copyright 2013 Intel Corporation.
# All Rights Reserved.
#
# 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.
"""
CPU monitor based on virt driver to retrieve CPU information
"""
from oslo_log import log as logging
from oslo_utils import timeutils
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__)
class Monitor(base.CPUMonitorBase):
"""CPU monitor that uses the virt driver's get_host_cpu_stats() call."""
def __init__(self, resource_tracker):
super(Monitor, self).__init__(resource_tracker)
self.source = CONF.compute_driver
self.driver = resource_tracker.driver
self._data = {}
self._cpu_stats = {}
def populate_metrics(self, metric_list):
self._update_data()
for name in self.get_metric_names():
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 = {}
self._data["timestamp"] = timeutils.utcnow()
# Extract node's CPU statistics.
try:
stats = self.driver.get_host_cpu_stats()
self._data["cpu.user.time"] = stats["user"]
self._data["cpu.kernel.time"] = stats["kernel"]
self._data["cpu.idle.time"] = stats["idle"]
self._data["cpu.iowait.time"] = stats["iowait"]
self._data["cpu.frequency"] = stats["frequency"]
except (NotImplementedError, TypeError, KeyError):
LOG.exception(_LE("Not all properties needed are implemented "
"in the compute driver"))
raise exception.ResourceMonitorError(
monitor=self.__class__.__name__)
# The compute driver API returns the absolute values for CPU times.
# We compute the utilization percentages for each specific CPU time
# after calculating the delta between the current reading and the
# previous reading.
stats["total"] = (stats["user"] + stats["kernel"]
+ stats["idle"] + stats["iowait"])
cputime = float(stats["total"] - self._cpu_stats.get("total", 0))
# NOTE(jwcroppe): Convert all the `perc` values to their integer forms
# since pre-conversion their values are within the range [0, 1] and the
# objects.MonitorMetric.value field requires an integer.
perc = (stats["user"] - self._cpu_stats.get("user", 0)) / cputime
self._data["cpu.user.percent"] = int(perc * 100)
perc = (stats["kernel"] - self._cpu_stats.get("kernel", 0)) / cputime
self._data["cpu.kernel.percent"] = int(perc * 100)
perc = (stats["idle"] - self._cpu_stats.get("idle", 0)) / cputime
self._data["cpu.idle.percent"] = int(perc * 100)
perc = (stats["iowait"] - self._cpu_stats.get("iowait", 0)) / cputime
self._data["cpu.iowait.percent"] = int(perc * 100)
# Compute the current system-wide CPU utilization as a percentage.
used = stats["user"] + stats["kernel"] + stats["iowait"]
prev_used = (self._cpu_stats.get("user", 0)
+ self._cpu_stats.get("kernel", 0)
+ self._cpu_stats.get("iowait", 0))
perc = (used - prev_used) / cputime
self._data["cpu.percent"] = int(perc * 100)
self._cpu_stats = stats.copy()