From 0c6f11cf88bf1a13a723879de46ec616678d2e0b Mon Sep 17 00:00:00 2001 From: Pradeep Kilambi Date: Mon, 1 Feb 2016 13:56:56 -0500 Subject: [PATCH] Skip duplicate meter definitions Closes-bug: #1536498 Change-Id: I531405d0153257ece38e2053a24d5c07cf4de90f --- ceilometer/meter/notifications.py | 13 +++++--- .../tests/unit/meter/test_notifications.py | 31 +++++++++++++++---- ...-duplicate-meter-def-0420164f6a95c50c.yaml | 10 ++++++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/skip-duplicate-meter-def-0420164f6a95c50c.yaml diff --git a/ceilometer/meter/notifications.py b/ceilometer/meter/notifications.py index ba4abddc..4104f679 100644 --- a/ceilometer/meter/notifications.py +++ b/ceilometer/meter/notifications.py @@ -23,7 +23,7 @@ from stevedore import extension from ceilometer.agent import plugin_base from ceilometer import declarative -from ceilometer.i18n import _LE +from ceilometer.i18n import _LE, _LW from ceilometer import sample from ceilometer import utils @@ -182,8 +182,13 @@ class ProcessMeterNotifications(plugin_base.NotificationBase): {}, cfg.CONF.meter.meter_definitions_cfg_file, pkg_resources.resource_filename(__name__, "data/meters.yaml")) - definitions = [] + definitions = {} for meter_cfg in reversed(meters_cfg['metric']): + if meter_cfg.get('name') in definitions: + # skip duplicate meters + LOG.warning(_LW("Skipping duplicate meter definition %s") + % meter_cfg) + continue if (meter_cfg.get('volume') != 1 or not cfg.CONF.notification.disable_non_metric_meters): try: @@ -193,8 +198,8 @@ class ProcessMeterNotifications(plugin_base.NotificationBase): % dict(err=six.text_type(me))) LOG.error(errmsg) else: - definitions.append(md) - return definitions + definitions[meter_cfg['name']] = md + return definitions.values() def get_targets(self, conf): """Return a sequence of oslo_messaging.Target diff --git a/ceilometer/tests/unit/meter/test_notifications.py b/ceilometer/tests/unit/meter/test_notifications.py index d100a563..e93ceb52 100644 --- a/ceilometer/tests/unit/meter/test_notifications.py +++ b/ceilometer/tests/unit/meter/test_notifications.py @@ -349,12 +349,11 @@ class TestMeterProcessing(test.BaseTestCase): resource_id="$.payload.resource_id", project_id="$.payload.project_id")]}) self._load_meter_def_file(cfg) - c = list(self.handler.process_notification(NOTIFICATION)) - self.assertEqual(2, len(c)) - s1 = c[0].as_dict() - self.assertEqual('test2', s1['name']) - s2 = c[1].as_dict() - self.assertEqual('test1', s2['name']) + data = list(self.handler.process_notification(NOTIFICATION)) + self.assertEqual(2, len(data)) + expected_names = ['test1', 'test2'] + for s in data: + self.assertTrue(s.as_dict()['name'] in expected_names) def test_unmatched_meter(self): cfg = yaml.dump( @@ -674,3 +673,23 @@ class TestMeterProcessing(test.BaseTestCase): self.assertEqual(1600, s1['volume']) self.assertEqual("prefix-tianst.sh.intel.com", s1['resource_id']) + + def test_duplicate_meter(self): + cfg = yaml.dump( + {'metric': [dict(name="test1", + event_type="test.create", + type="delta", + unit="B", + volume="$.payload.volume", + resource_id="$.payload.resource_id", + project_id="$.payload.project_id"), + dict(name="test1", + event_type="test.create", + type="delta", + unit="B", + volume="$.payload.volume", + resource_id="$.payload.resource_id", + project_id="$.payload.project_id")]}) + self._load_meter_def_file(cfg) + c = list(self.handler.process_notification(NOTIFICATION)) + self.assertEqual(1, len(c)) diff --git a/releasenotes/notes/skip-duplicate-meter-def-0420164f6a95c50c.yaml b/releasenotes/notes/skip-duplicate-meter-def-0420164f6a95c50c.yaml new file mode 100644 index 00000000..b98b79e8 --- /dev/null +++ b/releasenotes/notes/skip-duplicate-meter-def-0420164f6a95c50c.yaml @@ -0,0 +1,10 @@ + + +--- +fixes: + - > + [`bug 1536498 `_] + Patch to fix duplicate meter definitions causing duplicate samples. + If a duplicate is found, log a warning and skip the meter definition. + Note that the first occurance of a meter will be used and any following + duplicates will be skipped from processing.