From 9c6360a15dd809658653b11a077020fc5f807f49 Mon Sep 17 00:00:00 2001 From: Yadnesh Kulkarni Date: Wed, 27 Dec 2023 09:17:50 -0500 Subject: [PATCH] Add maximum fan rpm to hardware.ipmi.fan metrics Maximum rpm value can be used to calculate fan usage in percent. Ceilometer doesn't handle this calculation, instead this must be processed in metrics visuzaliation tools (like Prometheus or Grafana). Rpm values are not included if the hardware itself reported fan usage in percent. Change-Id: I77e3949c8a16e135f9bc1a2a43e170d0ea909f19 --- ceilometer/ipmi/pollsters/sensor.py | 19 +++++++++++++++++++ .../unit/ipmi/notifications/ipmi_test_data.py | 19 +++++++++++++++++++ .../tests/unit/ipmi/pollsters/test_sensor.py | 18 ++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/ceilometer/ipmi/pollsters/sensor.py b/ceilometer/ipmi/pollsters/sensor.py index 19d11d4fb3..4fbc93c075 100644 --- a/ceilometer/ipmi/pollsters/sensor.py +++ b/ceilometer/ipmi/pollsters/sensor.py @@ -107,6 +107,10 @@ class SensorPollster(plugin_base.PollsterBase): 'node': self.conf.host } + extra_metadata = self.get_extra_sensor_metadata(sensor_data) + if extra_metadata: + metadata.update(extra_metadata) + yield sample.Sample( name='hardware.ipmi.%s' % self.METRIC.lower(), type=sample.TYPE_GAUGE, @@ -117,6 +121,11 @@ class SensorPollster(plugin_base.PollsterBase): resource_id=resource_id, resource_metadata=metadata) + def get_extra_sensor_metadata(self, sensor_data): + # override get_extra_sensor_metadata to add specific metrics for + # each sensor + return {} + class TemperatureSensorPollster(SensorPollster): METRIC = 'Temperature' @@ -129,6 +138,16 @@ class CurrentSensorPollster(SensorPollster): class FanSensorPollster(SensorPollster): METRIC = 'Fan' + def get_extra_sensor_metadata(self, sensor_data): + try: + return { + "maximum_rpm": sensor_data['Normal Maximum'], + } + except KeyError: + # Maximum rpm might not be reported when usage + # is reported as percent + return {} + class VoltageSensorPollster(SensorPollster): METRIC = 'Voltage' diff --git a/ceilometer/tests/unit/ipmi/notifications/ipmi_test_data.py b/ceilometer/tests/unit/ipmi/notifications/ipmi_test_data.py index f5ed8159ec..043a7df1de 100644 --- a/ceilometer/tests/unit/ipmi/notifications/ipmi_test_data.py +++ b/ceilometer/tests/unit/ipmi/notifications/ipmi_test_data.py @@ -606,6 +606,25 @@ FAN_DATA = { } +FAN_DATA_PERCENT = { + 'Fan 1 (0x23)': { + 'Sensor ID': 'Fan 1 (0x23)', + 'Entity ID': '7.1 (System Board)', + 'Sensor Type (Threshold)': 'Fan (0x04)', + 'Sensor Reading': '47.040 (+/- 0) percent', + 'Status': 'ok', + 'Positive Hysteresis': 'Unspecified', + 'Negative Hysteresis': 'Unspecified', + 'Minimum sensor range': 'Unspecified', + 'Maximum sensor range': 'Unspecified', + 'Event Message Control': 'Global Disable Only', + 'Readable Thresholds': '', + 'Settable Thresholds': '', + 'Assertions Enabled': '' + } +} + + VOLTAGE_DATA = { 'Planar 12V (0x18)': { 'Status': 'ok', diff --git a/ceilometer/tests/unit/ipmi/pollsters/test_sensor.py b/ceilometer/tests/unit/ipmi/pollsters/test_sensor.py index 471157192f..a35e4234e0 100644 --- a/ceilometer/tests/unit/ipmi/pollsters/test_sensor.py +++ b/ceilometer/tests/unit/ipmi/pollsters/test_sensor.py @@ -28,6 +28,10 @@ FAN_SENSOR_DATA = { 'Fan': ipmi_test_data.FAN_DATA } +FAN_SENSOR_DATA_PERCENT = { + 'Fan': ipmi_test_data.FAN_DATA_PERCENT +} + VOLTAGE_SENSOR_DATA = { 'Voltage': ipmi_test_data.VOLTAGE_DATA } @@ -108,6 +112,20 @@ class TestFanSensorPollster(base.TestPollsterBase): self._verify_metering(12, float(7140), self.CONF.host) +class TestFanPercentSensorPollster(base.TestPollsterBase): + + def fake_sensor_data(self, sensor_type): + return FAN_SENSOR_DATA_PERCENT + + def make_pollster(self): + return sensor.FanSensorPollster(self.CONF) + + def test_get_samples(self): + self._test_get_samples() + + self._verify_metering(1, float(47.04), self.CONF.host) + + class TestCurrentSensorPollster(base.TestPollsterBase): def fake_sensor_data(self, sensor_type):