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:
parent
2eceb3c8ab
commit
b5d44d3aaf
@ -2832,8 +2832,7 @@ class ConductorManager(base_manager.BaseConductorManager):
|
|||||||
message = {'message_id': uuidutils.generate_uuid(),
|
message = {'message_id': uuidutils.generate_uuid(),
|
||||||
'instance_uuid': instance_uuid,
|
'instance_uuid': instance_uuid,
|
||||||
'node_uuid': node_uuid,
|
'node_uuid': node_uuid,
|
||||||
'timestamp': datetime.datetime.utcnow(),
|
'timestamp': datetime.datetime.utcnow()}
|
||||||
'event_type': 'hardware.ipmi.metrics.update'}
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lock_purpose = 'getting sensors data'
|
lock_purpose = 'getting sensors data'
|
||||||
@ -2846,6 +2845,16 @@ class ConductorManager(base_manager.BaseConductorManager):
|
|||||||
'%s as it is in maintenance mode',
|
'%s as it is in maintenance mode',
|
||||||
task.node.uuid)
|
task.node.uuid)
|
||||||
continue
|
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)
|
task.driver.management.validate(task)
|
||||||
sensors_data = task.driver.management.get_sensors_data(
|
sensors_data = task.driver.management.get_sensors_data(
|
||||||
@ -2879,7 +2888,7 @@ class ConductorManager(base_manager.BaseConductorManager):
|
|||||||
self._filter_out_unsupported_types(sensors_data))
|
self._filter_out_unsupported_types(sensors_data))
|
||||||
if message['payload']:
|
if message['payload']:
|
||||||
self.sensors_notifier.info(
|
self.sensors_notifier.info(
|
||||||
context, "hardware.ipmi.metrics", message)
|
context, ev_type, message)
|
||||||
finally:
|
finally:
|
||||||
# Yield on every iteration
|
# Yield on every iteration
|
||||||
eventlet.sleep(0)
|
eventlet.sleep(0)
|
||||||
|
@ -5592,8 +5592,9 @@ class SensorsTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
|
|||||||
expected_result = {}
|
expected_result = {}
|
||||||
self.assertEqual(expected_result, actual_result)
|
self.assertEqual(expected_result, actual_result)
|
||||||
|
|
||||||
|
@mock.patch.object(messaging.Notifier, 'info', autospec=True)
|
||||||
@mock.patch.object(task_manager, 'acquire')
|
@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()
|
nodes = queue.Queue()
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
nodes.put_nowait(('fake_uuid-%d' % i, 'fake-hardware', '', None))
|
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 = acquire_mock.return_value.__enter__.return_value
|
||||||
task.node.maintenance = False
|
task.node.maintenance = False
|
||||||
|
task.node.driver = 'fake'
|
||||||
|
task.node.name = 'fake_node'
|
||||||
get_sensors_data_mock = task.driver.management.get_sensors_data
|
get_sensors_data_mock = task.driver.management.get_sensors_data
|
||||||
validate_mock = task.driver.management.validate
|
validate_mock = task.driver.management.validate
|
||||||
get_sensors_data_mock.return_value = 'fake-sensor-data'
|
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, acquire_mock.call_count)
|
||||||
self.assertEqual(5, validate_mock.call_count)
|
self.assertEqual(5, validate_mock.call_count)
|
||||||
self.assertEqual(5, get_sensors_data_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')
|
@mock.patch.object(task_manager, 'acquire')
|
||||||
def test_send_sensor_task_shutdown(self, acquire_mock):
|
def test_send_sensor_task_shutdown(self, acquire_mock):
|
||||||
|
@ -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.
|
Loading…
x
Reference in New Issue
Block a user