systemd: check version for availability of properties (#1413)
The dbus property 'SystemState' and the timer property 'LastTriggerUSec' were added in version 212 of systemd. Check that the version of systemd is higher than 212 before attempting to query these propertiesf755e3b74b
dedabea4b3
Resolves issue #291 Signed-off-by: Paul Gier <pgier@redhat.com>
This commit is contained in:
parent
d3478a207e
commit
8c3de12c22
|
@ -20,6 +20,7 @@
|
||||||
* [ENHANCEMENT] Include additional XFS runtime statistics. #1423
|
* [ENHANCEMENT] Include additional XFS runtime statistics. #1423
|
||||||
* [ENHANCEMENT] Report non-fatal collection errors in the exporter metric. #1439
|
* [ENHANCEMENT] Report non-fatal collection errors in the exporter metric. #1439
|
||||||
* [ENHANCEMENT] Expose IPVS firewall mark as a label #1455
|
* [ENHANCEMENT] Expose IPVS firewall mark as a label #1455
|
||||||
|
* [ENHANCEMENT] Add check for systemd version before attempting to query certain metrics. #1413
|
||||||
* [BUGFIX] Renamed label `state` to `name` on `node_systemd_service_restart_total`. #1393
|
* [BUGFIX] Renamed label `state` to `name` on `node_systemd_service_restart_total`. #1393
|
||||||
* [BUGFIX] Fix netdev nil reference on Darwin #1414
|
* [BUGFIX] Fix netdev nil reference on Darwin #1414
|
||||||
* [BUGFIX] Strip path.rootfs from mountpoint labels #1421
|
* [BUGFIX] Strip path.rootfs from mountpoint labels #1421
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -29,6 +30,13 @@ import (
|
||||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// minSystemdVersionSystemState is the minimum SystemD version for availability of
|
||||||
|
// the 'SystemState' manager property and the timer property 'LastTriggerUSec'
|
||||||
|
// https://github.com/prometheus/node_exporter/issues/291
|
||||||
|
minSystemdVersionSystemState = 212
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
unitWhitelist = kingpin.Flag("collector.systemd.unit-whitelist", "Regexp of systemd units to whitelist. Units must both match whitelist and not match blacklist to be included.").Default(".+").String()
|
unitWhitelist = kingpin.Flag("collector.systemd.unit-whitelist", "Regexp of systemd units to whitelist. Units must both match whitelist and not match blacklist to be included.").Default(".+").String()
|
||||||
unitBlacklist = kingpin.Flag("collector.systemd.unit-blacklist", "Regexp of systemd units to blacklist. Units must both match whitelist and not match blacklist to be included.").Default(".+\\.(automount|device|mount|scope|slice)").String()
|
unitBlacklist = kingpin.Flag("collector.systemd.unit-blacklist", "Regexp of systemd units to blacklist. Units must both match whitelist and not match blacklist to be included.").Default(".+\\.(automount|device|mount|scope|slice)").String()
|
||||||
|
@ -50,6 +58,8 @@ type systemdCollector struct {
|
||||||
socketAcceptedConnectionsDesc *prometheus.Desc
|
socketAcceptedConnectionsDesc *prometheus.Desc
|
||||||
socketCurrentConnectionsDesc *prometheus.Desc
|
socketCurrentConnectionsDesc *prometheus.Desc
|
||||||
socketRefusedConnectionsDesc *prometheus.Desc
|
socketRefusedConnectionsDesc *prometheus.Desc
|
||||||
|
systemdVersionDesc *prometheus.Desc
|
||||||
|
systemdVersion int
|
||||||
unitWhitelistPattern *regexp.Regexp
|
unitWhitelistPattern *regexp.Regexp
|
||||||
unitBlacklistPattern *regexp.Regexp
|
unitBlacklistPattern *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
@ -103,9 +113,18 @@ func NewSystemdCollector() (Collector, error) {
|
||||||
socketRefusedConnectionsDesc := prometheus.NewDesc(
|
socketRefusedConnectionsDesc := prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, subsystem, "socket_refused_connections_total"),
|
prometheus.BuildFQName(namespace, subsystem, "socket_refused_connections_total"),
|
||||||
"Total number of refused socket connections", []string{"name"}, nil)
|
"Total number of refused socket connections", []string{"name"}, nil)
|
||||||
|
systemdVersionDesc := prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(namespace, subsystem, "version"),
|
||||||
|
"Detected systemd version", []string{}, nil)
|
||||||
unitWhitelistPattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *unitWhitelist))
|
unitWhitelistPattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *unitWhitelist))
|
||||||
unitBlacklistPattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *unitBlacklist))
|
unitBlacklistPattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *unitBlacklist))
|
||||||
|
|
||||||
|
systemdVersion := getSystemdVersion()
|
||||||
|
if systemdVersion < minSystemdVersionSystemState {
|
||||||
|
log.Warnf("Detected systemd version %v is lower than minimum %v", systemdVersion, minSystemdVersionSystemState)
|
||||||
|
log.Warn("Some systemd state and timer metrics will not be available")
|
||||||
|
}
|
||||||
|
|
||||||
return &systemdCollector{
|
return &systemdCollector{
|
||||||
unitDesc: unitDesc,
|
unitDesc: unitDesc,
|
||||||
unitStartTimeDesc: unitStartTimeDesc,
|
unitStartTimeDesc: unitStartTimeDesc,
|
||||||
|
@ -118,6 +137,8 @@ func NewSystemdCollector() (Collector, error) {
|
||||||
socketAcceptedConnectionsDesc: socketAcceptedConnectionsDesc,
|
socketAcceptedConnectionsDesc: socketAcceptedConnectionsDesc,
|
||||||
socketCurrentConnectionsDesc: socketCurrentConnectionsDesc,
|
socketCurrentConnectionsDesc: socketCurrentConnectionsDesc,
|
||||||
socketRefusedConnectionsDesc: socketRefusedConnectionsDesc,
|
socketRefusedConnectionsDesc: socketRefusedConnectionsDesc,
|
||||||
|
systemdVersionDesc: systemdVersionDesc,
|
||||||
|
systemdVersion: systemdVersion,
|
||||||
unitWhitelistPattern: unitWhitelistPattern,
|
unitWhitelistPattern: unitWhitelistPattern,
|
||||||
unitBlacklistPattern: unitBlacklistPattern,
|
unitBlacklistPattern: unitBlacklistPattern,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -127,7 +148,7 @@ func NewSystemdCollector() (Collector, error) {
|
||||||
// to reduce wait time for responses.
|
// to reduce wait time for responses.
|
||||||
func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
begin := time.Now()
|
begin := time.Now()
|
||||||
conn, err := c.newDbus()
|
conn, err := newSystemdDbusConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get dbus connection: %s", err)
|
return fmt.Errorf("couldn't get dbus connection: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -179,13 +200,15 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Add(1)
|
if c.systemdVersion >= minSystemdVersionSystemState {
|
||||||
go func() {
|
wg.Add(1)
|
||||||
defer wg.Done()
|
go func() {
|
||||||
begin = time.Now()
|
defer wg.Done()
|
||||||
c.collectTimers(conn, ch, units)
|
begin = time.Now()
|
||||||
log.Debugf("systemd collectTimers took %f", time.Since(begin).Seconds())
|
c.collectTimers(conn, ch, units)
|
||||||
}()
|
log.Debugf("systemd collectTimers took %f", time.Since(begin).Seconds())
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -195,9 +218,15 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
log.Debugf("systemd collectSockets took %f", time.Since(begin).Seconds())
|
log.Debugf("systemd collectSockets took %f", time.Since(begin).Seconds())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
begin = time.Now()
|
if c.systemdVersion >= minSystemdVersionSystemState {
|
||||||
err = c.collectSystemState(conn, ch)
|
begin = time.Now()
|
||||||
log.Debugf("systemd collectSystemState took %f", time.Since(begin).Seconds())
|
err = c.collectSystemState(conn, ch)
|
||||||
|
log.Debugf("systemd collectSystemState took %f", time.Since(begin).Seconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.systemdVersionDesc, prometheus.GaugeValue, float64(c.systemdVersion))
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +398,7 @@ func (c *systemdCollector) collectSystemState(conn *dbus.Conn, ch chan<- prometh
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *systemdCollector) newDbus() (*dbus.Conn, error) {
|
func newSystemdDbusConn() (*dbus.Conn, error) {
|
||||||
if *systemdPrivate {
|
if *systemdPrivate {
|
||||||
return dbus.NewSystemdConnection()
|
return dbus.NewSystemdConnection()
|
||||||
}
|
}
|
||||||
|
@ -424,3 +453,24 @@ func filterUnits(units []unit, whitelistPattern, blacklistPattern *regexp.Regexp
|
||||||
|
|
||||||
return filtered
|
return filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSystemdVersion() int {
|
||||||
|
conn, err := newSystemdDbusConn()
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Unable to get systemd dbus connection, defaulting systemd version to 0: %s", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
version, err := conn.GetManagerProperty("Version")
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Unable to get systemd version property, defaulting to 0")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
version = strings.Replace(version, "\"", "", 2)
|
||||||
|
v, err := strconv.Atoi(version)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Got invalid systemd version: %v", version)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue