Fix wrong CPU metric value in metrics_filter

CPU metrics are reported as a normalized value in [0,1].
When scheduler reads the data as MonitorMetric object, as part
of update_from_compute_node(), the value of the metric gets
lost due to a wrong type conversion, typecasting into an Integer,
reduces it to 0.

Note:
 - It may seem unintuitive that to fix the same, we are not changing
   the type of metric from Integer to Float. Please refer the
   discussions -
   * https://review.openstack.org/#/c/243825/
   * https://review.openstack.org/#/c/216923/
 - To summarize, we are trying to save some 'possible' downstream consumer
   of metrics updates from compute nodes, i.e. consuming from AMPQ, from
   software upgrade scenarios.

Change-Id: Ib504af33e05dfc4d7e97b52682e27befc67d784a
Closes-bug: #1514997
(cherry picked from commit ddb3c4e26f)
This commit is contained in:
Surojit Pathak 2015-11-25 19:21:24 +00:00 committed by Mohammed Naser
parent acb2dc5e27
commit c0dfe42382
2 changed files with 24 additions and 2 deletions

View File

@ -97,8 +97,18 @@ class MonitorMetricList(base.ObjectListBase, base.NovaObject):
:returns: a MonitorMetricList Object.
"""
metrics = jsonutils.loads(metrics) if metrics else []
metric_list = [
MonitorMetric(**metric) for metric in metrics]
# NOTE(suro-patz): While instantiating the MonitorMetric() from
# JSON-ified string, we need to re-convert the
# normalized metrics to avoid truncation to 0 by
# typecasting into an integer.
metric_list = []
for metric in metrics:
if ('value' in metric and metric['name'] in
FIELDS_REQUIRING_CONVERSION):
metric['value'] = metric['value'] * 100
metric_list.append(MonitorMetric(**metric))
return MonitorMetricList(objects=metric_list)
# NOTE(jaypipes): This method exists to convert the object to the

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_serialization import jsonutils
from oslo_utils import timeutils
from nova import objects
@ -73,6 +74,17 @@ class _TestMonitorMetricObject(object):
source='nova.virt.libvirt.driver')
self.assertEqual(_monitor_numa_metric_spec, obj.to_dict())
def test_conversion_in_monitor_metric_list_from_json(self):
spec_list = [_monitor_metric_spec, _monitor_metric_perc_spec]
metrics = objects.MonitorMetricList.from_json(
jsonutils.dumps(spec_list))
for metric, spec in zip(metrics, spec_list):
exp = spec['value']
if (spec['name'] in
objects.monitor_metric.FIELDS_REQUIRING_CONVERSION):
exp = spec['value'] * 100
self.assertEqual(exp, metric.value)
class TestMonitorMetricObject(test_objects._LocalTest,
_TestMonitorMetricObject):