From 7aa1d057e275faba4945abd927a7f4a457d71345 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Thu, 5 Sep 2024 12:00:52 +0200 Subject: [PATCH] Add system shutdown timestamp Add a metric for the scheduled shutdown time from systemd. Signed-off-by: Ben Kochie --- collector/systemd_linux.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/collector/systemd_linux.go b/collector/systemd_linux.go index e0d35bcd..c7fa5ab8 100644 --- a/collector/systemd_linux.go +++ b/collector/systemd_linux.go @@ -68,6 +68,7 @@ type systemdCollector struct { unitTasksCurrentDesc *prometheus.Desc unitTasksMaxDesc *prometheus.Desc systemRunningDesc *prometheus.Desc + systemShutdownDesc *prometheus.Desc summaryDesc *prometheus.Desc nRestartsDesc *prometheus.Desc timerLastTriggerDesc *prometheus.Desc @@ -112,6 +113,11 @@ func NewSystemdCollector(logger log.Logger) (Collector, error) { "Whether the system is operational (see 'systemctl is-system-running')", nil, nil, ) + systemShutdownDesc := prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "system_shutdown_timestamp"), + "Time for a scheduled shutdown (see 'systemctl status systemd-shutdownd.service')", + nil, nil, + ) summaryDesc := prometheus.NewDesc( prometheus.BuildFQName(namespace, subsystem, "units"), "Summary of systemd unit states", []string{"state"}, nil) @@ -161,6 +167,7 @@ func NewSystemdCollector(logger log.Logger) (Collector, error) { unitTasksCurrentDesc: unitTasksCurrentDesc, unitTasksMaxDesc: unitTasksMaxDesc, systemRunningDesc: systemRunningDesc, + systemShutdownDesc: systemShutdownDesc, summaryDesc: summaryDesc, nRestartsDesc: nRestartsDesc, timerLastTriggerDesc: timerLastTriggerDesc, @@ -265,6 +272,10 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { level.Debug(c.logger).Log("msg", "collectSystemState took", "duration_seconds", time.Since(begin).Seconds()) } + begin = time.Now() + err = c.collectScheduledShutdownMetrics(conn, ch) + level.Debug(c.logger).Log("msg", "collectScheduledShutdownMetrics took", "duration_seconds", time.Since(begin).Seconds()) + return err } @@ -343,6 +354,23 @@ func (c *systemdCollector) collectSockets(conn *dbus.Conn, ch chan<- prometheus. } } +func (c *systemdCollector) collectScheduledShutdownMetrics(conn *dbus.Conn, ch chan<- prometheus.Metric) error { + var shutdownTimeUsec uint64 + + timestampValue, err := conn.GetServicePropertyContext(context.TODO(), "org.freedesktop.login1", "ScheduledShutdown") + if err != nil { + level.Debug(c.logger).Log("msg", "couldn't get ScheduledShutdown", "err", err) + return errors.New("Couldn't get ScheduledShutdown property") + } + shutdownTimeUsec = timestampValue.Value.Value().(uint64) + + ch <- prometheus.MustNewConstMetric( + c.systemShutdownDesc, prometheus.GaugeValue, + float64(shutdownTimeUsec)/1e6, + ) + return nil +} + func (c *systemdCollector) collectUnitStartTimeMetrics(conn *dbus.Conn, ch chan<- prometheus.Metric, units []unit) { var startTimeUsec uint64