Merge pull request #34 from msherman64/ipmi-chassis

Ipmi-chassis power on/off state
This commit is contained in:
Conrad Hoffmann 2019-10-15 10:58:58 +02:00 committed by GitHub
commit 85875ebc14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 4 deletions

View File

@ -249,6 +249,13 @@ returned from the BMC. Example:
ipmi_bmc_info{firmware_revision="2.52",manufacturer_id="Dell Inc. (674)"} 1 ipmi_bmc_info{firmware_revision="2.52",manufacturer_id="Dell Inc. (674)"} 1
### Chassis Power State
This metric is only provided if the `chassis` collector is enabled.
The metric `ipmi_chassis_power_state` shows the current chassis power state of the machine.
The value is 1 for poweron, and 0 otherwise.
### Power consumption ### Power consumption
This metric is only provided if the `dcmi` collector is enabled. This metric is only provided if the `dcmi` collector is enabled.

View File

@ -28,6 +28,7 @@ const (
var ( var (
ipmiDCMICurrentPowerRegex = regexp.MustCompile(`^Current Power\s*:\s*(?P<value>[0-9.]*)\s*Watts.*`) ipmiDCMICurrentPowerRegex = regexp.MustCompile(`^Current Power\s*:\s*(?P<value>[0-9.]*)\s*Watts.*`)
ipmiChassisPowerRegex = regexp.MustCompile(`^System Power\s*:\s(?P<value>.*)`)
bmcInfoFirmwareRevisionRegex = regexp.MustCompile(`^Firmware Revision\s*:\s*(?P<value>[0-9.]*).*`) bmcInfoFirmwareRevisionRegex = regexp.MustCompile(`^Firmware Revision\s*:\s*(?P<value>[0-9.]*).*`)
bmcInfoManufacturerIDRegex = regexp.MustCompile(`^Manufacturer ID\s*:\s*(?P<value>.*)`) bmcInfoManufacturerIDRegex = regexp.MustCompile(`^Manufacturer ID\s*:\s*(?P<value>.*)`)
) )
@ -145,6 +146,13 @@ var (
nil, nil,
) )
chassisPowerState = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "chassis", "power_state"),
"Current power state (1=on, 0=off).",
[]string{},
nil,
)
bmcInfo = prometheus.NewDesc( bmcInfo = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "bmc", "info"), prometheus.BuildFQName(namespace, "bmc", "info"),
"Constant metric with value '1' providing details about the BMC.", "Constant metric with value '1' providing details about the BMC.",
@ -248,6 +256,10 @@ func bmcInfoOutput(target ipmiTarget) ([]byte, error) {
return freeipmiOutput("bmc-info", target, "--get-device-id") return freeipmiOutput("bmc-info", target, "--get-device-id")
} }
func ipmiChassisOutput(target ipmiTarget) ([]byte, error) {
return freeipmiOutput("ipmi-chassis", target, "--get-chassis-status")
}
func splitMonitoringOutput(impiOutput []byte, excludeSensorIds []int64) ([]sensorData, error) { func splitMonitoringOutput(impiOutput []byte, excludeSensorIds []int64) ([]sensorData, error) {
var result []sensorData var result []sensorData
@ -314,6 +326,17 @@ func getCurrentPowerConsumption(ipmiOutput []byte) (float64, error) {
return strconv.ParseFloat(value, 64) return strconv.ParseFloat(value, 64)
} }
func getChassisPowerState(ipmiOutput []byte) (float64, error) {
value, err := getValue(ipmiOutput, ipmiChassisPowerRegex)
if err != nil {
return -1, err
}
if value == "on" {
return 1, err
}
return 0, err
}
func getBMCInfoFirmwareRevision(ipmiOutput []byte) (string, error) { func getBMCInfoFirmwareRevision(ipmiOutput []byte) (string, error) {
return getValue(ipmiOutput, bmcInfoFirmwareRevisionRegex) return getValue(ipmiOutput, bmcInfoFirmwareRevisionRegex)
} }
@ -438,6 +461,25 @@ func collectDCMI(ch chan<- prometheus.Metric, target ipmiTarget) (int, error) {
return 1, nil return 1, nil
} }
func collectChassisState(ch chan<- prometheus.Metric, target ipmiTarget) (int, error) {
output, err := ipmiChassisOutput(target)
if err != nil {
log.Debugf("Failed to collect ipmi-chassis data from %s: %s", targetName(target.host), err)
return 0, err
}
currentChassisPowerState, err := getChassisPowerState(output)
if err != nil {
log.Errorf("Failed to parse ipmi-chassis data from %s: %s", targetName(target.host), err)
return 0, err
}
ch <- prometheus.MustNewConstMetric(
chassisPowerState,
prometheus.GaugeValue,
currentChassisPowerState,
)
return 1, nil
}
func collectBmcInfo(ch chan<- prometheus.Metric, target ipmiTarget) (int, error) { func collectBmcInfo(ch chan<- prometheus.Metric, target ipmiTarget) (int, error) {
output, err := bmcInfoOutput(target) output, err := bmcInfoOutput(target)
if err != nil { if err != nil {
@ -501,6 +543,8 @@ func (c collector) Collect(ch chan<- prometheus.Metric) {
up, _ = collectDCMI(ch, target) up, _ = collectDCMI(ch, target)
case "bmc": case "bmc":
up, _ = collectBmcInfo(ch, target) up, _ = collectBmcInfo(ch, target)
case "chassis":
up, _ = collectChassisState(ch, target)
} }
markCollectorUp(ch, collector, up) markCollectorUp(ch, collector, up)
} }

View File

@ -39,7 +39,7 @@ type IPMIConfig struct {
XXX map[string]interface{} `yaml:",inline"` XXX map[string]interface{} `yaml:",inline"`
} }
var emptyConfig = IPMIConfig{Collectors: []string{"ipmi", "dcmi", "bmc"}} var emptyConfig = IPMIConfig{Collectors: []string{"ipmi", "dcmi", "bmc", "chassis"}}
// CollectorName is used for unmarshaling the list of collectors in the yaml config file // CollectorName is used for unmarshaling the list of collectors in the yaml config file
type CollectorName string type CollectorName string
@ -78,7 +78,7 @@ func (s *IPMIConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
return err return err
} }
for _, c := range s.Collectors { for _, c := range s.Collectors {
if !(c == "ipmi" || c == "dcmi" || c == "bmc") { if !(c == "ipmi" || c == "dcmi" || c == "bmc" || c == "chassis") {
return fmt.Errorf("unknown collector name: %s", c) return fmt.Errorf("unknown collector name: %s", c)
} }
} }

View File

@ -4,11 +4,12 @@
# In most cases, this should work without using a config file at all. # In most cases, this should work without using a config file at all.
modules: modules:
default: default:
# Available collectors are bmc, ipmi, and dcmi # Available collectors are bmc, ipmi, chassis, and dcmi
collectors: collectors:
- bmc - bmc
- ipmi - ipmi
- dcmi - dcmi
- chassis
# Got any sensors you don't care about? Add them here. # Got any sensors you don't care about? Add them here.
exclude_sensor_ids: exclude_sensor_ids:
- 2 - 2

View File

@ -21,11 +21,12 @@ modules:
# to (session-timeout * #-of-collectors) milliseconds, so set the scrape # to (session-timeout * #-of-collectors) milliseconds, so set the scrape
# timeout in Prometheus accordingly. # timeout in Prometheus accordingly.
timeout: 10000 timeout: 10000
# Available collectors are bmc, ipmi, and dcmi # Available collectors are bmc, ipmi, chassis, and dcmi
# If not specified, all three are used # If not specified, all three are used
collectors: collectors:
- bmc - bmc
- ipmi - ipmi
- chassis
# Got any sensors you don't care about? Add them here. # Got any sensors you don't care about? Add them here.
exclude_sensor_ids: exclude_sensor_ids:
- 2 - 2