collector: systemd: collect whether the system is operational

pull/174/head
Rémi Audebert 2015-12-17 19:30:35 +01:00
parent 87ccaa39c9
commit 8628d60125
2 changed files with 38 additions and 6 deletions

View File

@ -24,6 +24,7 @@ import (
type systemdCollector struct { type systemdCollector struct {
unitDesc *prometheus.Desc unitDesc *prometheus.Desc
systemRunningDesc *prometheus.Desc
} }
var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"} var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"}
@ -35,13 +36,21 @@ func init() {
// Takes a prometheus registry and returns a new Collector exposing // Takes a prometheus registry and returns a new Collector exposing
// systemd statistics. // systemd statistics.
func NewSystemdCollector() (Collector, error) { func NewSystemdCollector() (Collector, error) {
const subsystem = "systemd"
unitDesc := prometheus.NewDesc( unitDesc := prometheus.NewDesc(
prometheus.BuildFQName(Namespace, "systemd", "unit_state"), prometheus.BuildFQName(Namespace, subsystem, "unit_state"),
"Systemd unit", []string{"name", "state"}, nil, "Systemd unit", []string{"name", "state"}, nil,
) )
systemRunningDesc := prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "system_running"),
"Whether the system is operational (see 'systemctl is-system-running')",
nil, nil,
)
return &systemdCollector{ return &systemdCollector{
unitDesc: unitDesc, unitDesc: unitDesc,
systemRunningDesc: systemRunningDesc,
}, nil }, nil
} }
@ -50,13 +59,18 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) (err error) {
if err != nil { if err != nil {
return fmt.Errorf("couldn't get units states: %s", err) return fmt.Errorf("couldn't get units states: %s", err)
} }
c.collectUnitStatusMetrics(ch, units)
c.collectMetrics(ch, units) systemState, err := c.getSystemState()
if err != nil {
return fmt.Errorf("couldn't get system state: %s", err)
}
c.collectSystemState(ch, systemState)
return nil return nil
} }
func (c *systemdCollector) collectMetrics(ch chan<- prometheus.Metric, units []dbus.UnitStatus) { func (c *systemdCollector) collectUnitStatusMetrics(ch chan<- prometheus.Metric, units []dbus.UnitStatus) {
for _, unit := range units { for _, unit := range units {
for _, stateName := range unitStatesName { for _, stateName := range unitStatesName {
isActive := 0.0 isActive := 0.0
@ -70,6 +84,14 @@ func (c *systemdCollector) collectMetrics(ch chan<- prometheus.Metric, units []d
} }
} }
func (c *systemdCollector) collectSystemState(ch chan<- prometheus.Metric, systemState string) {
isSystemRunning := 0.0
if systemState == `"running"` {
isSystemRunning = 1.0
}
ch <- prometheus.MustNewConstMetric(c.systemRunningDesc, prometheus.GaugeValue, isSystemRunning)
}
func (c *systemdCollector) listUnits() ([]dbus.UnitStatus, error) { func (c *systemdCollector) listUnits() ([]dbus.UnitStatus, error) {
conn, err := dbus.New() conn, err := dbus.New()
if err != nil { if err != nil {
@ -79,3 +101,13 @@ func (c *systemdCollector) listUnits() ([]dbus.UnitStatus, error) {
conn.Close() conn.Close()
return units, err return units, err
} }
func (c *systemdCollector) getSystemState() (state string, err error) {
conn, err := dbus.New()
if err != nil {
return "", fmt.Errorf("couldn't get dbus connection: %s", err)
}
state, err = conn.GetManagerProperty("SystemState")
conn.Close()
return state, err
}

View File

@ -69,6 +69,6 @@ func TestSystemdCollectorDoesntCrash(t *testing.T) {
fixtures := getUnitListFixtures() fixtures := getUnitListFixtures()
collector := (c).(*systemdCollector) collector := (c).(*systemdCollector)
for _, units := range fixtures { for _, units := range fixtures {
collector.collectMetrics(sink, units) collector.collectUnitStatusMetrics(sink, units)
} }
} }