Generic ceilometer notification listener module
Change-Id: I00be2bf7eb07d1352b4cc2e28e384736e1b363b4
diff --git a/xos/api/tenant/monitoring/dashboard/ceilometerdashboard.py b/xos/api/tenant/monitoring/dashboard/ceilometerdashboard.py
index 1333d5a..1ab8d75 100644
--- a/xos/api/tenant/monitoring/dashboard/ceilometerdashboard.py
+++ b/xos/api/tenant/monitoring/dashboard/ceilometerdashboard.py
@@ -253,6 +253,35 @@
# Here will be the cached Meter objects, that will be reused for
# repeated listing.
self._cached_meters = {}
+ self._cached_all_meters = []
+
+ def get_all(self):
+ if not self._cached_all_meters:
+ for meter in self._ceilometer_meter_list:
+ meter_info = self._all_meters_info.get(meter['name'], None)
+ if meter_info:
+ label = meter_info["label"]
+ description = meter_info["description"]
+ meter_category = meter_info["type"]
+ else:
+ label = ""
+ description = ""
+ meter_category = "Other"
+ meter["label"] = label
+ meter["description"] = description
+ meter["category"] = meter_category
+ if meter["project_id"] in self.tenant_map.keys():
+ meter["slice"] = self.tenant_map[meter["project_id"]]["slice"]
+ meter["service"] = self.tenant_map[meter["project_id"]]["service"]
+ else:
+ meter["slice"] = meter["project_id"]
+ meter["service"] = "Other"
+ if meter["resource_id"] in self.resource_map.keys():
+ meter["resource_name"] = self.resource_map[meter["resource_id"]]
+
+ self._cached_all_meters.append(meter)
+
+ return self._cached_all_meters
def list_all(self, only_meters=None, except_meters=None):
"""Returns a list of meters based on the meters names.
@@ -1253,18 +1282,7 @@
tenant_map = getTenantControllerTenantMap(request.user)
resource_map = get_resource_map(request, ceilometer_url=tenant_ceilometer_url, query=query)
meters = Meters(request, ceilometer_url=tenant_ceilometer_url, query=query, tenant_map=tenant_map, resource_map=resource_map)
- services = {
- _('Nova'): meters.list_nova(),
- _('Neutron'): meters.list_neutron(),
- _('VSG'): meters.list_vcpe(),
- _('VOLT'): meters.list_volt(),
- _('SDN'): meters.list_sdn(),
- _('BROADVIEW'): meters.list_broadview(),
- }
- meters = []
- for service,smeters in services.iteritems():
- meters.extend(smeters)
- return Response(meters)
+ return Response(meters.get_all())
class MeterStatisticsList(APIView):
method_kind = "list"
@@ -1325,43 +1343,34 @@
#Statistics query for all meter
resource_map = get_resource_map(request, ceilometer_url=tenant_ceilometer_url, query=query)
meters = Meters(request, ceilometer_url=tenant_ceilometer_url, query=query, tenant_map=tenant_map, resource_map=resource_map)
- services = {
- _('Nova'): meters.list_nova(),
- _('Neutron'): meters.list_neutron(),
- _('VSG'): meters.list_vcpe(),
- _('VOLT'): meters.list_volt(),
- _('SDN'): meters.list_sdn(),
- _('BROADVIEW'): meters.list_broadview(),
- }
report_rows = []
- for service,meters in services.items():
- for meter in meters:
- query = make_query(tenant_id=meter["project_id"],resource_id=meter["resource_id"])
- if additional_query:
- query = query + additional_query
- try:
- statistics = statistic_list(request, meter["name"],
- ceilometer_url=tenant_ceilometer_url, query=query, period=3600*24)
- except Exception as e:
- logger.error('Exception during statistics query for meter %(meter)s and reason:%(reason)s' % {'meter':meter["name"], 'reason':str(e)})
- statistics = None
+ for meter in meters.get_all():
+ query = make_query(tenant_id=meter["project_id"],resource_id=meter["resource_id"])
+ if additional_query:
+ query = query + additional_query
+ try:
+ statistics = statistic_list(request, meter["name"],
+ ceilometer_url=tenant_ceilometer_url, query=query, period=3600*24)
+ except Exception as e:
+ logger.error('Exception during statistics query for meter %(meter)s and reason:%(reason)s' % {'meter':meter["name"], 'reason':str(e)})
+ statistics = None
- if not statistics:
- continue
- statistic = statistics[-1]
- row = {"name": 'none',
- "slice": meter["slice"],
- "project_id": meter["project_id"],
- "service": meter["service"],
- "resource_id": meter["resource_id"],
- "resource_name": meter["resource_name"],
- "meter": meter["name"],
- "description": meter["description"],
- "category": service,
- "time": statistic["period_end"],
- "value": statistic["avg"],
- "unit": meter["unit"]}
- report_rows.append(row)
+ if not statistics:
+ continue
+ statistic = statistics[-1]
+ row = {"name": 'none',
+ "slice": meter["slice"],
+ "project_id": meter["project_id"],
+ "service": meter["service"],
+ "resource_id": meter["resource_id"],
+ "resource_name": meter["resource_name"],
+ "meter": meter["name"],
+ "description": meter["description"],
+ "category": meter["category"],
+ "time": statistic["period_end"],
+ "value": statistic["avg"],
+ "unit": meter["unit"]}
+ report_rows.append(row)
return Response(report_rows)
diff --git a/xos/synchronizer/ceilometer/ceilometer-plugins/network/ext_services/cord/__init__.py b/xos/synchronizer/ceilometer/ceilometer-plugins/network/ext_services/cord/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/xos/synchronizer/ceilometer/ceilometer-plugins/network/ext_services/cord/__init__.py
diff --git a/xos/synchronizer/ceilometer/ceilometer-plugins/network/ext_services/cord/notifications.py b/xos/synchronizer/ceilometer/ceilometer-plugins/network/ext_services/cord/notifications.py
new file mode 100644
index 0000000..a832b01
--- /dev/null
+++ b/xos/synchronizer/ceilometer/ceilometer-plugins/network/ext_services/cord/notifications.py
@@ -0,0 +1,69 @@
+#
+# Copyright 2012 New Dream Network, LLC (DreamHost)
+#
+# 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.
+"""Handler for producing network counter messages from Neutron notification
+ events.
+
+"""
+
+import oslo_messaging
+from oslo_config import cfg
+
+from ceilometer.agent import plugin_base
+from oslo_log import log
+from ceilometer import sample
+
+OPTS = [
+ cfg.StrOpt('cord_control_exchange',
+ default='cord',
+ help="Exchange name for CORD related notifications."),
+]
+
+cfg.CONF.register_opts(OPTS)
+
+LOG = log.getLogger(__name__)
+
+
+class CORDNotificationBase(plugin_base.NotificationBase):
+
+ resource_name = None
+ event_types = ['cord*']
+
+ def get_targets(self,conf):
+ """Return a sequence of oslo.messaging.Target
+
+ This sequence is defining the exchange and topics to be connected for
+ this plugin.
+ """
+ LOG.info("get_targets for CORD Notification Listener")
+ return [oslo_messaging.Target(topic=topic,
+ exchange=conf.cord_control_exchange)
+ for topic in self.get_notification_topics(conf)]
+
+ def process_notification(self, message):
+ LOG.info('Received CORD notification')
+ if 'counter_type' not in message['payload']:
+ meter_type = sample.TYPE_GAUGE
+ else:
+ meter_type = sample.TYPE_GAUGE if 'gauge' in message['payload']['counter_type'].lower() else sample.TYPE_DELTA if 'delta' in message['payload']['counter_type'].lower() else sample.TYPE_GAUGE
+
+ yield sample.Sample.from_notification(
+ name=message['payload']['counter_name'],
+ type=meter_type,
+ unit=message['payload']['counter_unit'],
+ volume=message['payload']['counter_volume'],
+ user_id=message['payload']['user_id'],
+ project_id=message['payload']['tenant_id'],
+ resource_id=message['payload']['resource_id'],
+ message=message)
diff --git a/xos/test/monitoring_test_exampleservicemetrics.yaml b/xos/test/monitoring_test_exampleservicemetrics.yaml
new file mode 100644
index 0000000..ee7fed1
--- /dev/null
+++ b/xos/test/monitoring_test_exampleservicemetrics.yaml
@@ -0,0 +1,9 @@
+---
+- hosts: localhost
+
+ vars_files:
+ - vars/defaults.yml
+
+ roles:
+ - common
+ - test-exampleservicemonitoring
diff --git a/xos/test/roles/common/tasks/main.yml b/xos/test/roles/common/tasks/main.yml
index 32c9613..6a9bbe6 100644
--- a/xos/test/roles/common/tasks/main.yml
+++ b/xos/test/roles/common/tasks/main.yml
@@ -13,5 +13,5 @@
retries: 5
delay: 60
with_items:
- - http://localhost:8888/api/service/monitoring/
- - http://localhost:8888/api/tenant/monitoring/monitoringchannel/
+ - http://localhost:9000/api/service/monitoring/
+ - http://localhost:9000/api/tenant/monitoring/monitoringchannel/
diff --git a/xos/test/roles/test-exampleservicemonitoring/tasks/main.yml b/xos/test/roles/test-exampleservicemonitoring/tasks/main.yml
new file mode 100644
index 0000000..0190d80
--- /dev/null
+++ b/xos/test/roles/test-exampleservicemonitoring/tasks/main.yml
@@ -0,0 +1,28 @@
+---
+- name: Validate Monitoring URL is completely UP and metrics contain vSG related metrics
+ uri:
+ url: "{{monitoringservice.results[1].json[0].ceilometer_url}}v2/meters"
+ status_code: 200
+ return_content: yes
+ body_format: json
+ HEADER_Content-Type: "application/json"
+ register: metrics
+ until: "(metrics.status == 200) and (metrics.content|from_json|length>0) and ('exampleservice' in metrics.content)"
+ retries: 5
+ delay: 10
+
+- name: assert exampleservice metrics exampleservice.apache.total.accesses are present
+ assert:
+ that: "'exampleservice.apache.total.accesses' in metrics.content"
+ msg: "Metrics does not contains exampleservice.apache.total.accesses related statistics"
+
+- name: assert exampleservice metrics exampleservice.apache.uptime are present
+ assert:
+ that: "'exampleservice.apache.uptime' in metrics.content"
+ msg: "Metrics does not contains exampleservice.apache.uptime related statistics"
+
+- name: assert exampleservice metrics exampleservice.apache.reqpersec are present
+ assert:
+ that: "'exampleservice.apache.reqpersec' in metrics.content"
+ msg: "Metrics does not contains exampleservice.apache.reqpersec related statistics"
+