From 8628d601250d3d83f11ebe11b5167c4201a02e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Audebert?= Date: Thu, 17 Dec 2015 19:30:35 +0100 Subject: [PATCH] collector: systemd: collect whether the system is operational --- collector/systemd_linux.go | 42 +++++++++++++++++++++++++++++---- collector/systemd_linux_test.go | 2 +- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/collector/systemd_linux.go b/collector/systemd_linux.go index 10f239a0..914fe11c 100644 --- a/collector/systemd_linux.go +++ b/collector/systemd_linux.go @@ -23,7 +23,8 @@ import ( ) type systemdCollector struct { - unitDesc *prometheus.Desc + unitDesc *prometheus.Desc + systemRunningDesc *prometheus.Desc } var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"} @@ -35,13 +36,21 @@ func init() { // Takes a prometheus registry and returns a new Collector exposing // systemd statistics. func NewSystemdCollector() (Collector, error) { + const subsystem = "systemd" + unitDesc := prometheus.NewDesc( - prometheus.BuildFQName(Namespace, "systemd", "unit_state"), + prometheus.BuildFQName(Namespace, subsystem, "unit_state"), "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{ - unitDesc: unitDesc, + unitDesc: unitDesc, + systemRunningDesc: systemRunningDesc, }, nil } @@ -50,13 +59,18 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) (err error) { if err != nil { 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 } -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 _, stateName := range unitStatesName { 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) { conn, err := dbus.New() if err != nil { @@ -79,3 +101,13 @@ func (c *systemdCollector) listUnits() ([]dbus.UnitStatus, error) { conn.Close() 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 +} diff --git a/collector/systemd_linux_test.go b/collector/systemd_linux_test.go index f5390140..c6217203 100644 --- a/collector/systemd_linux_test.go +++ b/collector/systemd_linux_test.go @@ -69,6 +69,6 @@ func TestSystemdCollectorDoesntCrash(t *testing.T) { fixtures := getUnitListFixtures() collector := (c).(*systemdCollector) for _, units := range fixtures { - collector.collectMetrics(sink, units) + collector.collectUnitStatusMetrics(sink, units) } }