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 <tom@compton.nu>
This commit is contained in:
Tom Hughes 2021-11-14 10:32:52 +00:00
parent b806738818
commit 5d7b5cbb57
2 changed files with 34 additions and 13 deletions

View File

@ -42,13 +42,20 @@ var (
nil, nil,
) )
fanSpeedDesc = prometheus.NewDesc( fanSpeedRPMDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "fan_speed", "rpm"), prometheus.BuildFQName(namespace, "fan_speed", "rpm"),
"Fan speed in rotations per minute.", "Fan speed in rotations per minute.",
[]string{"id", "name"}, []string{"id", "name"},
nil, 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( fanSpeedStateDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "fan_speed", "state"), prometheus.BuildFQName(namespace, "fan_speed", "state"),
"Reported state of a fan speed sensor (0=nominal, 1=warning, 2=critical).", "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 { switch data.Unit {
case "RPM": case "RPM":
collectTypedSensor(ch, fanSpeedDesc, fanSpeedStateDesc, state, data) collectTypedSensor(ch, fanSpeedRPMDesc, fanSpeedStateDesc, state, data, 1.0)
case "C": case "C":
collectTypedSensor(ch, temperatureDesc, temperatureStateDesc, state, data) collectTypedSensor(ch, temperatureDesc, temperatureStateDesc, state, data, 1.0)
case "A": case "A":
collectTypedSensor(ch, currentDesc, currentStateDesc, state, data) collectTypedSensor(ch, currentDesc, currentStateDesc, state, data, 1.0)
case "V": case "V":
collectTypedSensor(ch, voltageDesc, voltageStateDesc, state, data) collectTypedSensor(ch, voltageDesc, voltageStateDesc, state, data, 1.0)
case "W": 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: default:
collectGenericSensor(ch, state, data) 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) { func (c IPMICollector) Describe(ch chan<- *prometheus.Desc) {
ch <- sensorStateDesc ch <- sensorStateDesc
ch <- sensorValueDesc ch <- sensorValueDesc
ch <- fanSpeedDesc ch <- fanSpeedRPMDesc
ch <- fanSpeedRatioDesc
ch <- fanSpeedStateDesc ch <- fanSpeedStateDesc
ch <- temperatureDesc ch <- temperatureDesc
ch <- temperatureStateDesc ch <- temperatureStateDesc
@ -193,11 +208,11 @@ func (c IPMICollector) Describe(ch chan<- *prometheus.Desc) {
ch <- powerStateDesc 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( ch <- prometheus.MustNewConstMetric(
desc, desc,
prometheus.GaugeValue, prometheus.GaugeValue,
data.Value, data.Value*scale,
strconv.FormatInt(data.ID, 10), strconv.FormatInt(data.ID, 10),
data.Name, data.Name,
) )

View File

@ -111,14 +111,20 @@ sensor ID and the sensor name as labels. Example:
### Fan speed sensors ### Fan speed sensors
Fan speed sensors measure fan speed in rotations per minute (RPM) and their Fan speed sensors measure fan speed in rotations per minute (RPM) or as a
state usually reflects the speed being to low, indicating the fan might be percentage of the maximum speed, and their state usually reflects the speed
broken. For each fan speed sensor, two metrics are exported (state and value), being to low, indicating the fan might be broken. For each fan speed sensor,
using the sensor ID and the sensor name as labels. Example: 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_rpm{id="12",name="Fan1A"} 4560
ipmi_fan_speed_state{id="12",name="Fan1A"} 0 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
Voltage sensors measure a voltage in Volts. For each voltage sensor, two Voltage sensors measure a voltage in Volts. For each voltage sensor, two