from typing import List
import gnocchiclient.exceptions
+from ceilometerclient.v2 import client as ceilometer_client
from gnocchiclient.v1 import client as gnocchi_client
from keystoneauth1 import session
+from keystoneauth1.exceptions import EndpointNotFound
from keystoneauth1.identity import v3
from osm_mon.collector.metric import Metric
+from osm_mon.collector.utils import CollectorUtils
from osm_mon.collector.vnf_collectors.base_vim import BaseVimCollector
from osm_mon.collector.vnf_metric import VnfMetric
-from osm_mon.core.auth import AuthManager
from osm_mon.core.common_db import CommonDbClient
from osm_mon.core.config import Config
METRIC_MAPPINGS = {
"average_memory_utilization": "memory.usage",
- "disk_read_ops": "disk.read.requests",
- "disk_write_ops": "disk.write.requests",
- "disk_read_bytes": "disk.read.bytes",
- "disk_write_bytes": "disk.write.bytes",
- "packets_dropped": "interface.if_dropped",
- "packets_received": "interface.if_packets",
- "packets_sent": "interface.if_packets",
+ "disk_read_ops": "disk.read.requests.rate",
+ "disk_write_ops": "disk.write.requests.rate",
+ "disk_read_bytes": "disk.read.bytes.rate",
+ "disk_write_bytes": "disk.write.bytes.rate",
+ "packets_in_dropped": "network.outgoing.packets.drop",
+ "packets_out_dropped": "network.incoming.packets.drop",
+ "packets_received": "network.incoming.packets.rate",
+ "packets_sent": "network.outgoing.packets.rate",
"cpu_utilization": "cpu_util",
}
+INTERFACE_METRICS = ['packets_in_dropped', 'packets_out_dropped', 'packets_received', 'packets_sent']
+
class OpenstackCollector(BaseVimCollector):
def __init__(self, config: Config, vim_account_id: str):
super().__init__(config, vim_account_id)
self.conf = config
self.common_db = CommonDbClient(config)
- self.auth_manager = AuthManager(config)
+ self.backend = self._get_backend(vim_account_id)
+ self.client = self._build_client(vim_account_id)
self.granularity = self._get_granularity(vim_account_id)
- self.gnocchi_client = self._build_gnocchi_client(vim_account_id)
def _get_resource_uuid(self, nsr_id, vnf_member_index, vdur_name) -> str:
vdur = self.common_db.get_vdur(nsr_id, vnf_member_index, vdur_name)
return vdur['vim-id']
def _build_gnocchi_client(self, vim_account_id: str) -> gnocchi_client.Client:
- creds = self.auth_manager.get_credentials(vim_account_id)
- verify_ssl = self.auth_manager.is_verify_ssl(vim_account_id)
+ creds = CollectorUtils.get_credentials(vim_account_id)
+ verify_ssl = CollectorUtils.is_verify_ssl(creds)
auth = v3.Password(auth_url=creds.url,
username=creds.user,
password=creds.password,
sess = session.Session(auth=auth, verify=verify_ssl)
return gnocchi_client.Client(session=sess)
- def _get_granularity(self, vim_account_id: str):
- creds = self.auth_manager.get_credentials(vim_account_id)
+ def _build_ceilometer_client(self, vim_account_id: str) -> ceilometer_client.Client:
+ creds = CollectorUtils.get_credentials(vim_account_id)
+ verify_ssl = CollectorUtils.is_verify_ssl(creds)
+ auth = v3.Password(auth_url=creds.url,
+ username=creds.user,
+ password=creds.password,
+ project_name=creds.tenant_name,
+ project_domain_id='default',
+ user_domain_id='default')
+ sess = session.Session(auth=auth, verify=verify_ssl)
+ return ceilometer_client.Client(session=sess)
+
+ def _get_granularity(self, vim_account_id):
+ creds = CollectorUtils.get_credentials(vim_account_id)
vim_config = json.loads(creds.config)
if 'granularity' in vim_config:
return int(vim_config['granularity'])
if 'monitoring-param' in vdu:
for param in vdu['monitoring-param']:
metric_name = param['nfvi-metric']
- gnocchi_metric_name = METRIC_MAPPINGS[metric_name]
- delta = 10 * self.granularity
- start_date = datetime.datetime.now() - datetime.timedelta(seconds=delta)
- resource_id = self._get_resource_uuid(nsr_id, vnf_member_index, vdur['name'])
+ openstack_metric_name = METRIC_MAPPINGS[metric_name]
try:
- measures = self.gnocchi_client.metric.get_measures(gnocchi_metric_name,
+ resource_id = self._get_resource_uuid(nsr_id, vnf_member_index, vdur['name'])
+ except ValueError:
+ log.warning(
+ "Could not find resource_uuid for vdur %s, vnf_member_index %s, nsr_id %s. "
+ "Was it recently deleted?",
+ vdur['name'], vnf_member_index, nsr_id)
+ continue
+ if self.backend == 'ceilometer':
+ measures = self.client.samples.list(meter_name=openstack_metric_name, limit=1, q=[
+ {'field': 'resource_id', 'op': 'eq', 'value': resource_id}])
+ if measures:
+ metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], metric_name,
+ measures[0].counter_volume)
+ metrics.append(metric)
+ if self.backend == 'gnocchi':
+ delta = 10 * self.granularity
+ start_date = datetime.datetime.now() - datetime.timedelta(seconds=delta)
+ if metric_name in INTERFACE_METRICS:
+ total_measure = None
+ interfaces = self.client.resource.search(resource_type='instance_network_interface',
+ query={'=': {'instance_id': resource_id}})
+ for interface in interfaces:
+ try:
+ measures = self.client.metric.get_measures(openstack_metric_name,
+ start=start_date,
+ resource_id=interface['id'],
+ granularity=self.granularity)
+ if measures:
+ if not total_measure:
+ total_measure = 0.0
+ total_measure += measures[-1][2]
+
+ except gnocchiclient.exceptions.NotFound as e:
+ log.debug("No metric %s found for interface %s: %s", openstack_metric_name,
+ interface['id'], e)
+ if total_measure:
+ metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], metric_name,
+ total_measure)
+ metrics.append(metric)
+ else:
+ try:
+ measures = self.client.metric.get_measures(openstack_metric_name,
start=start_date,
resource_id=resource_id,
granularity=self.granularity)
- if len(measures):
- metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], metric_name, measures[-1][2])
- metrics.append(metric)
- except gnocchiclient.exceptions.NotFound as e:
- log.debug("No metric found: %s", e)
- pass
+ if measures:
+ metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], metric_name,
+ measures[-1][2])
+ metrics.append(metric)
+ except gnocchiclient.exceptions.NotFound as e:
+ log.debug("No metric %s found for instance %s: %s", openstack_metric_name, resource_id,
+ e)
+
+ else:
+ raise Exception('Unknown client class: %s', self.client)
return metrics
+
+ def _build_client(self, vim_account_id):
+ if self.backend == 'ceilometer':
+ return self._build_ceilometer_client(vim_account_id)
+ elif self.backend == 'gnocchi':
+ return self._build_gnocchi_client(vim_account_id)
+ else:
+ raise Exception('Unknown metric backend: %s', self.backend)
+
+ def _get_backend(self, vim_account_id):
+ try:
+ gnocchi = self._build_gnocchi_client(vim_account_id)
+ gnocchi.resource.list(limit=1)
+ return 'gnocchi'
+ except EndpointNotFound:
+ try:
+ ceilometer = self._build_ceilometer_client(vim_account_id)
+ ceilometer.resources.list(limit=1)
+ return 'ceilometer'
+ except Exception:
+ log.exception('Error trying to determine metric backend')
+ raise Exception('Could not determine metric backend')