From 5d7b5cbb57d37011c591a618005189a21f08e254 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Sun, 14 Nov 2021 10:32:52 +0000 Subject: [PATCH] Add support for fan sensors which report as a percentage Fan sensors on HP servers report speed as a percentage of the maximum instead of a raw RPM value. Signed-off-by: Tom Hughes --- collector_ipmi.go | 33 ++++++++++++++++++++++++--------- docs/metrics.md | 14 ++++++++++---- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/collector_ipmi.go b/collector_ipmi.go index dfac986..11c9b90 100644 --- a/collector_ipmi.go +++ b/collector_ipmi.go @@ -42,13 +42,20 @@ var ( nil, ) - fanSpeedDesc = prometheus.NewDesc( + fanSpeedRPMDesc = prometheus.NewDesc( prometheus.BuildFQName(namespace, "fan_speed", "rpm"), "Fan speed in rotations per minute.", []string{"id", "name"}, nil, ) + fanSpeedRatioDesc = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "fan_speed", "ratio"), + "Fan speed as a proportion of the maximum speed.", + []string{"id", "name"}, + nil, + ) + fanSpeedStateDesc = prometheus.NewDesc( prometheus.BuildFQName(namespace, "fan_speed", "state"), "Reported state of a fan speed sensor (0=nominal, 1=warning, 2=critical).", @@ -162,15 +169,22 @@ func (c IPMICollector) Collect(result freeipmi.Result, ch chan<- prometheus.Metr switch data.Unit { case "RPM": - collectTypedSensor(ch, fanSpeedDesc, fanSpeedStateDesc, state, data) + collectTypedSensor(ch, fanSpeedRPMDesc, fanSpeedStateDesc, state, data, 1.0) case "C": - collectTypedSensor(ch, temperatureDesc, temperatureStateDesc, state, data) + collectTypedSensor(ch, temperatureDesc, temperatureStateDesc, state, data, 1.0) case "A": - collectTypedSensor(ch, currentDesc, currentStateDesc, state, data) + collectTypedSensor(ch, currentDesc, currentStateDesc, state, data, 1.0) case "V": - collectTypedSensor(ch, voltageDesc, voltageStateDesc, state, data) + collectTypedSensor(ch, voltageDesc, voltageStateDesc, state, data, 1.0) case "W": - collectTypedSensor(ch, powerDesc, powerStateDesc, state, data) + collectTypedSensor(ch, powerDesc, powerStateDesc, state, data, 1.0) + case "%": + switch data.Type { + case "Fan": + collectTypedSensor(ch, fanSpeedRatioDesc, fanSpeedStateDesc, state, data, 0.01) + default: + collectGenericSensor(ch, state, data) + } default: collectGenericSensor(ch, state, data) } @@ -181,7 +195,8 @@ func (c IPMICollector) Collect(result freeipmi.Result, ch chan<- prometheus.Metr func (c IPMICollector) Describe(ch chan<- *prometheus.Desc) { ch <- sensorStateDesc ch <- sensorValueDesc - ch <- fanSpeedDesc + ch <- fanSpeedRPMDesc + ch <- fanSpeedRatioDesc ch <- fanSpeedStateDesc ch <- temperatureDesc ch <- temperatureStateDesc @@ -193,11 +208,11 @@ func (c IPMICollector) Describe(ch chan<- *prometheus.Desc) { ch <- powerStateDesc } -func collectTypedSensor(ch chan<- prometheus.Metric, desc, stateDesc *prometheus.Desc, state float64, data freeipmi.SensorData) { +func collectTypedSensor(ch chan<- prometheus.Metric, desc, stateDesc *prometheus.Desc, state float64, data freeipmi.SensorData, scale float64) { ch <- prometheus.MustNewConstMetric( desc, prometheus.GaugeValue, - data.Value, + data.Value*scale, strconv.FormatInt(data.ID, 10), data.Name, ) diff --git a/docs/metrics.md b/docs/metrics.md index 48c45ce..8fcef3f 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -111,14 +111,20 @@ sensor ID and the sensor name as labels. Example: ### Fan speed sensors -Fan speed sensors measure fan speed in rotations per minute (RPM) and their -state usually reflects the speed being to low, indicating the fan might be -broken. For each fan speed sensor, two metrics are exported (state and value), -using the sensor ID and the sensor name as labels. Example: +Fan speed sensors measure fan speed in rotations per minute (RPM) or as a +percentage of the maximum speed, and their state usually reflects the speed +being to low, indicating the fan might be broken. For each fan speed sensor, +two metrics are exported (state and value), using the sensor ID and the +sensor name as labels. Example: ipmi_fan_speed_rpm{id="12",name="Fan1A"} 4560 ipmi_fan_speed_state{id="12",name="Fan1A"} 0 +or, for a percentage based fan: + + ipmi_fan_speed_ratio{id="58",name="Fan 1 DutyCycle"} 0.2195 + ipmi_fan_speed_state{id="58",name="Fan 1 DutyCycle"} 0 + ### Voltage sensors Voltage sensors measure a voltage in Volts. For each voltage sensor, two