Add infrastructure reliability monitoring
This commit is contained in:
57
ups.go
57
ups.go
@@ -10,20 +10,26 @@ import (
|
||||
)
|
||||
|
||||
type UPSMetrics struct {
|
||||
Available bool `json:"available"`
|
||||
Source string `json:"source"`
|
||||
Name string `json:"name"`
|
||||
Model string `json:"model"`
|
||||
Status string `json:"status"`
|
||||
StatusLabel string `json:"statusLabel"`
|
||||
ChargePercent *float64 `json:"chargePercent"`
|
||||
RuntimeSeconds *float64 `json:"runtimeSeconds"`
|
||||
LoadPercent *float64 `json:"loadPercent"`
|
||||
InputVoltage *float64 `json:"inputVoltage"`
|
||||
OutputVoltage *float64 `json:"outputVoltage"`
|
||||
InputFrequency *float64 `json:"inputFrequency"`
|
||||
BatteryVoltage *float64 `json:"batteryVoltage"`
|
||||
Temperature *float64 `json:"temperatureCelsius"`
|
||||
Available bool `json:"available"`
|
||||
Source string `json:"source"`
|
||||
Name string `json:"name"`
|
||||
Model string `json:"model"`
|
||||
Status string `json:"status"`
|
||||
StatusLabel string `json:"statusLabel"`
|
||||
ChargePercent *float64 `json:"chargePercent"`
|
||||
RuntimeSeconds *float64 `json:"runtimeSeconds"`
|
||||
LoadPercent *float64 `json:"loadPercent"`
|
||||
InputVoltage *float64 `json:"inputVoltage"`
|
||||
OutputVoltage *float64 `json:"outputVoltage"`
|
||||
InputFrequency *float64 `json:"inputFrequency"`
|
||||
BatteryVoltage *float64 `json:"batteryVoltage"`
|
||||
Temperature *float64 `json:"temperatureCelsius"`
|
||||
CommunicationOK bool `json:"communicationOk"`
|
||||
BatteryDate string `json:"batteryDate"`
|
||||
BatteryAgeDays int `json:"batteryAgeDays,omitempty"`
|
||||
ReplaceBattery bool `json:"replaceBattery"`
|
||||
LowBatteryCharge *float64 `json:"lowBatteryCharge,omitempty"`
|
||||
LowBatteryRuntime *float64 `json:"lowBatteryRuntime,omitempty"`
|
||||
}
|
||||
|
||||
type upsCollector struct {
|
||||
@@ -43,7 +49,13 @@ func (c *upsCollector) collect() UPSMetrics {
|
||||
} else if metrics, ok := readAPCUPSD(); ok {
|
||||
c.cached = metrics
|
||||
} else {
|
||||
c.cached = UPSMetrics{}
|
||||
if c.cached.Available || c.cached.Source != "" {
|
||||
c.cached.Available = false
|
||||
c.cached.CommunicationOK = false
|
||||
c.cached.StatusLabel = "Нет связи"
|
||||
} else {
|
||||
c.cached = UPSMetrics{}
|
||||
}
|
||||
}
|
||||
c.updatedAt = time.Now()
|
||||
return c.cached
|
||||
@@ -85,6 +97,7 @@ func readAPCUPSD() (UPSMetrics, bool) {
|
||||
"ups.load": raw["LOADPCT"], "input.voltage": raw["LINEV"],
|
||||
"output.voltage": raw["OUTPUTV"], "input.frequency": raw["LINEFREQ"],
|
||||
"battery.voltage": raw["BATTV"], "ups.temperature": raw["ITEMP"],
|
||||
"battery.date": raw["BATTDATE"], "battery.charge.low": raw["MBATTCHG"], "battery.runtime.low": minutesToSeconds(raw["MINTIMEL"]),
|
||||
}
|
||||
return upsFromValues("apcupsd", raw["UPSNAME"], values), true
|
||||
}
|
||||
@@ -102,14 +115,24 @@ func parseColonValues(output string) map[string]string {
|
||||
|
||||
func upsFromValues(source, name string, values map[string]string) UPSMetrics {
|
||||
status := values["ups.status"]
|
||||
return UPSMetrics{
|
||||
Available: true, Source: source, Name: name, Model: values["device.model"],
|
||||
metrics := UPSMetrics{
|
||||
Available: true, CommunicationOK: true, Source: source, Name: name, Model: values["device.model"],
|
||||
Status: status, StatusLabel: upsStatusLabel(status),
|
||||
ChargePercent: numberPointer(values["battery.charge"]), RuntimeSeconds: numberPointer(values["battery.runtime"]),
|
||||
LoadPercent: numberPointer(values["ups.load"]), InputVoltage: numberPointer(values["input.voltage"]),
|
||||
OutputVoltage: numberPointer(values["output.voltage"]), InputFrequency: numberPointer(values["input.frequency"]),
|
||||
BatteryVoltage: numberPointer(values["battery.voltage"]), Temperature: numberPointer(firstNonEmpty(values["ups.temperature"], values["battery.temperature"])),
|
||||
BatteryDate: firstNonEmpty(values["battery.date"], values["battery.mfr.date"]), ReplaceBattery: strings.Contains(status, "RB"), LowBatteryCharge: numberPointer(values["battery.charge.low"]), LowBatteryRuntime: numberPointer(values["battery.runtime.low"]),
|
||||
}
|
||||
if metrics.BatteryDate != "" {
|
||||
for _, layout := range []string{"2006/01/02", "2006-01-02", "01/02/2006", "02/01/2006"} {
|
||||
if date, err := time.Parse(layout, metrics.BatteryDate); err == nil {
|
||||
metrics.BatteryAgeDays = int(time.Since(date).Hours() / 24)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return metrics
|
||||
}
|
||||
|
||||
func numberPointer(value string) *float64 {
|
||||
|
||||
Reference in New Issue
Block a user