Merge pull request #2283 from prometheus/superq/fix_systemd_version

Refactor systemd version
pull/2216/merge
Ben Kochie 2022-02-22 14:33:05 +01:00 committed by GitHub
commit e3a18fdd37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 28 deletions

View File

@ -57,6 +57,8 @@ var (
enableTaskMetrics = kingpin.Flag("collector.systemd.enable-task-metrics", "Enables service unit tasks metrics unit_tasks_current and unit_tasks_max").Bool() enableTaskMetrics = kingpin.Flag("collector.systemd.enable-task-metrics", "Enables service unit tasks metrics unit_tasks_current and unit_tasks_max").Bool()
enableRestartsMetrics = kingpin.Flag("collector.systemd.enable-restarts-metrics", "Enables service unit metric service_restart_total").Bool() enableRestartsMetrics = kingpin.Flag("collector.systemd.enable-restarts-metrics", "Enables service unit metric service_restart_total").Bool()
enableStartTimeMetrics = kingpin.Flag("collector.systemd.enable-start-time-metrics", "Enables service unit metric unit_start_time_seconds").Bool() enableStartTimeMetrics = kingpin.Flag("collector.systemd.enable-start-time-metrics", "Enables service unit metric unit_start_time_seconds").Bool()
systemdVersionRE = regexp.MustCompile(`[0-9]{3,}(\.[0-9]+)?`)
) )
type systemdCollector struct { type systemdCollector struct {
@ -129,7 +131,7 @@ func NewSystemdCollector(logger log.Logger) (Collector, error) {
"Total number of refused socket connections", []string{"name"}, nil) "Total number of refused socket connections", []string{"name"}, nil)
systemdVersionDesc := prometheus.NewDesc( systemdVersionDesc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "version"), prometheus.BuildFQName(namespace, subsystem, "version"),
"Detected systemd version", []string{}, nil) "Detected systemd version", []string{"version"}, nil)
if *oldUnitExclude != "" { if *oldUnitExclude != "" {
if !unitExcludeSet { if !unitExcludeSet {
@ -152,12 +154,6 @@ func NewSystemdCollector(logger log.Logger) (Collector, error) {
level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *unitExclude) level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *unitExclude)
unitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *unitExclude)) unitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *unitExclude))
systemdVersion := getSystemdVersion(logger)
if systemdVersion < minSystemdVersionSystemState {
level.Warn(logger).Log("msg", "Detected systemd version is lower than minimum", "current", systemdVersion, "minimum", minSystemdVersionSystemState)
level.Warn(logger).Log("msg", "Some systemd state and timer metrics will not be available")
}
return &systemdCollector{ return &systemdCollector{
unitDesc: unitDesc, unitDesc: unitDesc,
unitStartTimeDesc: unitStartTimeDesc, unitStartTimeDesc: unitStartTimeDesc,
@ -171,7 +167,6 @@ func NewSystemdCollector(logger log.Logger) (Collector, error) {
socketCurrentConnectionsDesc: socketCurrentConnectionsDesc, socketCurrentConnectionsDesc: socketCurrentConnectionsDesc,
socketRefusedConnectionsDesc: socketRefusedConnectionsDesc, socketRefusedConnectionsDesc: socketRefusedConnectionsDesc,
systemdVersionDesc: systemdVersionDesc, systemdVersionDesc: systemdVersionDesc,
systemdVersion: systemdVersion,
unitIncludePattern: unitIncludePattern, unitIncludePattern: unitIncludePattern,
unitExcludePattern: unitExcludePattern, unitExcludePattern: unitExcludePattern,
logger: logger, logger: logger,
@ -188,6 +183,17 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
} }
defer conn.Close() defer conn.Close()
systemdVersion, systemdVersionFull := c.getSystemdVersion(conn)
if systemdVersion < minSystemdVersionSystemState {
level.Debug(c.logger).Log("msg", "Detected systemd version is lower than minimum, some systemd state and timer metrics will not be available", "current", systemdVersion, "minimum", minSystemdVersionSystemState)
}
ch <- prometheus.MustNewConstMetric(
c.systemdVersionDesc,
prometheus.GaugeValue,
systemdVersion,
systemdVersionFull,
)
allUnits, err := c.getAllUnits(conn) allUnits, err := c.getAllUnits(conn)
if err != nil { if err != nil {
return fmt.Errorf("couldn't get units: %w", err) return fmt.Errorf("couldn't get units: %w", err)
@ -234,7 +240,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
}() }()
} }
if c.systemdVersion >= minSystemdVersionSystemState { if systemdVersion >= minSystemdVersionSystemState {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
@ -252,15 +258,12 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
level.Debug(c.logger).Log("msg", "collectSockets took", "duration_seconds", time.Since(begin).Seconds()) level.Debug(c.logger).Log("msg", "collectSockets took", "duration_seconds", time.Since(begin).Seconds())
}() }()
if c.systemdVersion >= minSystemdVersionSystemState { if systemdVersion >= minSystemdVersionSystemState {
begin = time.Now() begin = time.Now()
err = c.collectSystemState(conn, ch) err = c.collectSystemState(conn, ch)
level.Debug(c.logger).Log("msg", "collectSystemState took", "duration_seconds", time.Since(begin).Seconds()) level.Debug(c.logger).Log("msg", "collectSystemState took", "duration_seconds", time.Since(begin).Seconds())
} }
ch <- prometheus.MustNewConstMetric(
c.systemdVersionDesc, prometheus.GaugeValue, float64(c.systemdVersion))
return err return err
} }
@ -488,24 +491,19 @@ func filterUnits(units []unit, includePattern, excludePattern *regexp.Regexp, lo
return filtered return filtered
} }
func getSystemdVersion(logger log.Logger) float64 { func (c *systemdCollector) getSystemdVersion(conn *dbus.Conn) (float64, string) {
conn, err := newSystemdDbusConn()
if err != nil {
level.Warn(logger).Log("msg", "Unable to get systemd dbus connection, defaulting systemd version to 0", "err", err)
return 0
}
defer conn.Close()
version, err := conn.GetManagerProperty("Version") version, err := conn.GetManagerProperty("Version")
if err != nil { if err != nil {
level.Warn(logger).Log("msg", "Unable to get systemd version property, defaulting to 0") level.Debug(c.logger).Log("msg", "Unable to get systemd version property, defaulting to 0")
return 0 return 0, ""
} }
re := regexp.MustCompile(`[0-9][0-9][0-9](\.[0-9]+)?`) version = strings.TrimPrefix(strings.TrimSuffix(version, `"`), `"`)
version = re.FindString(version) level.Debug(c.logger).Log("msg", "Got systemd version", "version", version)
v, err := strconv.ParseFloat(version, 64) parsedVersion := systemdVersionRE.FindString(version)
v, err := strconv.ParseFloat(parsedVersion, 64)
if err != nil { if err != nil {
level.Warn(logger).Log("msg", "Got invalid systemd version", "version", version) level.Debug(c.logger).Log("msg", "Got invalid systemd version", "version", version)
return 0 return 0, ""
} }
return v return v, version
} }