# For those usages not covered by the Apache License, Version 2.0 please
# contact: bdiaz@whitestack.com or glavado@whitestack.com
##
-import logging
from enum import Enum
+import logging
+import time
from typing import List
-import gnocchiclient.exceptions
from ceilometerclient import client as ceilometer_client
from ceilometerclient.exc import HTTPException
+import gnocchiclient.exceptions
from gnocchiclient.v1 import client as gnocchi_client
-from keystoneclient.v3 import client as keystone_client
from keystoneauth1.exceptions.catalog import EndpointNotFound
+from keystoneclient.v3 import client as keystone_client
from neutronclient.v2_0 import client as neutron_client
from osm_mon.collector.metric import Metric
from osm_mon.core.common_db import CommonDbClient
from osm_mon.core.config import Config
+
log = logging.getLogger(__name__)
METRIC_MAPPINGS = {
"packets_out_dropped": "network.incoming.packets.drop",
"packets_received": "network.incoming.packets.rate",
"packets_sent": "network.outgoing.packets.rate",
- "cpu_utilization": "cpu_util",
+ "cpu_utilization": "cpu",
+}
+
+METRIC_MULTIPLIERS = {
+ "cpu": 0.0000001
+}
+
+METRIC_AGGREGATORS = {
+ "cpu": "rate:mean"
}
INTERFACE_METRICS = ['packets_in_dropped', 'packets_out_dropped', 'packets_received', 'packets_sent']
def _collect_instance_metric(self, openstack_metric_name, resource_id):
value = None
try:
+ aggregation = METRIC_AGGREGATORS.get(openstack_metric_name)
+
measures = self.client.metric.get_measures(openstack_metric_name,
- resource_id=resource_id,
- limit=1)
+ aggregation=aggregation,
+ start=time.time() - 1200,
+ resource_id=resource_id)
+ # measures[-1][0] is the time of the reporting interval
+ # measures[-1][1] is the durcation of the reporting interval
+ # measures[-1][2] is the value of the metric
if measures:
value = measures[-1][2]
+ if aggregation:
+ # If this is an aggregate, we need to divide the total over the reported time period.
+ value = value / measures[-1][1]
+ if openstack_metric_name in METRIC_MULTIPLIERS:
+ value = value * METRIC_MULTIPLIERS[openstack_metric_name]
except gnocchiclient.exceptions.NotFound as e:
log.debug("No metric %s found for instance %s: %s", openstack_metric_name, resource_id,
e)
import datetime
from unittest import TestCase, mock
+import gnocchiclient
+
from osm_mon.collector.vnf_collectors.openstack import GnocchiBackend
from osm_mon.core.config import Config
@mock.patch.object(GnocchiBackend, '_build_neutron_client')
@mock.patch.object(GnocchiBackend, '_build_gnocchi_client')
- def test_collect_gnocchi_instance(self, build_gnocchi_client, build_neutron_client):
+ def test_collect_gnocchi_rate_instance(self, build_gnocchi_client, _):
mock_gnocchi_client = mock.Mock()
mock_gnocchi_client.metric.get_measures.return_value = [(datetime.datetime(2019, 4, 12, 15, 43,
tzinfo=datetime.timezone(
(datetime.datetime(2019, 4, 12, 15, 44,
tzinfo=datetime.timezone(
datetime.timedelta(0),
- '+00:00')), 60.0, 0.0333070363)]
+ '+00:00')), 60.0, 600000000)]
build_gnocchi_client.return_value = mock_gnocchi_client
backend = GnocchiBackend({'_id': 'test_uuid'})
- value = backend._collect_instance_metric('cpu_utilization', 'test_resource_id')
- self.assertEqual(value, 0.0333070363)
- mock_gnocchi_client.metric.get_measures.assert_called_once_with('cpu_utilization',
- limit=1,
+ value = backend._collect_instance_metric('cpu', 'test_resource_id')
+ self.assertEqual(value, 1.0)
+ mock_gnocchi_client.metric.get_measures.assert_called_once_with('cpu',
+ aggregation="rate:mean",
+ start=mock.ANY,
+ resource_id='test_resource_id')
+
+ @mock.patch.object(GnocchiBackend, '_build_neutron_client')
+ @mock.patch.object(GnocchiBackend, '_build_gnocchi_client')
+ def test_collect_gnocchi_non_rate_instance(self, build_gnocchi_client, _):
+ mock_gnocchi_client = mock.Mock()
+ mock_gnocchi_client.metric.get_measures.return_value = [(datetime.datetime(2019, 4, 12, 15, 43,
+ tzinfo=datetime.timezone(
+ datetime.timedelta(0),
+ '+00:00')), 60.0, 0.0345442539),
+ (datetime.datetime(2019, 4, 12, 15, 44,
+ tzinfo=datetime.timezone(
+ datetime.timedelta(0),
+ '+00:00')), 60.0, 128)]
+ build_gnocchi_client.return_value = mock_gnocchi_client
+
+ backend = GnocchiBackend({'_id': 'test_uuid'})
+ value = backend._collect_instance_metric('memory.usage', 'test_resource_id')
+ self.assertEqual(value, 128)
+ mock_gnocchi_client.metric.get_measures.assert_called_once_with('memory.usage',
+ aggregation=None,
+ start=mock.ANY,
+ resource_id='test_resource_id')
+
+ @mock.patch.object(GnocchiBackend, '_build_neutron_client')
+ @mock.patch.object(GnocchiBackend, '_build_gnocchi_client')
+ def test_collect_gnocchi_no_metric(self, build_gnocchi_client, _):
+ mock_gnocchi_client = mock.Mock()
+ mock_gnocchi_client.metric.get_measures.side_effect = gnocchiclient.exceptions.NotFound()
+ build_gnocchi_client.return_value = mock_gnocchi_client
+
+ backend = GnocchiBackend({'_id': 'test_uuid'})
+ value = backend._collect_instance_metric('memory.usage', 'test_resource_id')
+ self.assertIsNone(value)
+ mock_gnocchi_client.metric.get_measures.assert_called_once_with('memory.usage',
+ aggregation=None,
+ start=mock.ANY,
resource_id='test_resource_id')
@mock.patch.object(GnocchiBackend, '_build_neutron_client')