Make metrics usable

Metric notifications were hard coded with a value indicating
"ipmi" for all hardware types and management interfaces which
offer sensor data to be transmitted as a metric notification.

Also adds a node_name field to allow processors to leverage
the node name as opposed to needing ironic API or database access
to construct enough data to make metrics notifications usable.

Change-Id: I1116bd5812f3715bd7d6d1bf34df932f81702147
This commit is contained in:
Julia Kreger 2019-03-14 12:08:37 -07:00
parent 2eceb3c8ab
commit b5d44d3aaf
3 changed files with 44 additions and 4 deletions

View File

@ -2832,8 +2832,7 @@ class ConductorManager(base_manager.BaseConductorManager):
message = {'message_id': uuidutils.generate_uuid(),
'instance_uuid': instance_uuid,
'node_uuid': node_uuid,
'timestamp': datetime.datetime.utcnow(),
'event_type': 'hardware.ipmi.metrics.update'}
'timestamp': datetime.datetime.utcnow()}
try:
lock_purpose = 'getting sensors data'
@ -2846,6 +2845,16 @@ class ConductorManager(base_manager.BaseConductorManager):
'%s as it is in maintenance mode',
task.node.uuid)
continue
# Add the node name, as the name would be hand for other
# notifier plugins
message['node_name'] = task.node.name
# We should convey the proper hardware type,
# which previously was hard coded to ipmi, but other
# drivers were transmitting other values under the
# guise of ipmi.
ev_type = 'hardware.{driver}.metrics'.format(
driver=task.node.driver)
message['event_type'] = ev_type + '.update'
task.driver.management.validate(task)
sensors_data = task.driver.management.get_sensors_data(
@ -2879,7 +2888,7 @@ class ConductorManager(base_manager.BaseConductorManager):
self._filter_out_unsupported_types(sensors_data))
if message['payload']:
self.sensors_notifier.info(
context, "hardware.ipmi.metrics", message)
context, ev_type, message)
finally:
# Yield on every iteration
eventlet.sleep(0)

View File

@ -5592,8 +5592,9 @@ class SensorsTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
expected_result = {}
self.assertEqual(expected_result, actual_result)
@mock.patch.object(messaging.Notifier, 'info', autospec=True)
@mock.patch.object(task_manager, 'acquire')
def test_send_sensor_task(self, acquire_mock):
def test_send_sensor_task(self, acquire_mock, notifier_mock):
nodes = queue.Queue()
for i in range(5):
nodes.put_nowait(('fake_uuid-%d' % i, 'fake-hardware', '', None))
@ -5602,6 +5603,8 @@ class SensorsTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
task = acquire_mock.return_value.__enter__.return_value
task.node.maintenance = False
task.node.driver = 'fake'
task.node.name = 'fake_node'
get_sensors_data_mock = task.driver.management.get_sensors_data
validate_mock = task.driver.management.validate
get_sensors_data_mock.return_value = 'fake-sensor-data'
@ -5609,6 +5612,21 @@ class SensorsTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
self.assertEqual(5, acquire_mock.call_count)
self.assertEqual(5, validate_mock.call_count)
self.assertEqual(5, get_sensors_data_mock.call_count)
self.assertEqual(5, notifier_mock.call_count)
if six.PY2:
# bail out if python2 as matching fails to match the
# data structure becasue it requires the order to be consistent
# but the mock also records the call dictionary contents in
# random order changing with every invocation. :\
return
n_call = mock.call(mock.ANY, mock.ANY, 'hardware.fake.metrics',
{'event_type': 'hardware.fake.metrics.update',
'node_name': 'fake_node', 'timestamp': mock.ANY,
'message_id': mock.ANY,
'payload': 'fake-sensor-data',
'node_uuid': mock.ANY, 'instance_uuid': None})
notifier_mock.assert_has_calls([n_call, n_call, n_call,
n_call, n_call])
@mock.patch.object(task_manager, 'acquire')
def test_send_sensor_task_shutdown(self, acquire_mock):

View File

@ -0,0 +1,13 @@
---
features:
- |
Notification events for metrics data now contains a ``node_name``
field to assist operators with relating metrics data being transmitted
by the conductor service.
fixes:
- |
Notification event types now include the hardware type name string as
opposed to a static string of "ipmi". This allows event processors and
operators to understand what the actual notification event data source
is as opposed to having to rely upon fingerprints of the data to make
such determinations.