From 40dce45d8dfd5f89abc00eb94a4a252d755e0552 Mon Sep 17 00:00:00 2001 From: Paul Gier Date: Tue, 29 Jan 2019 16:54:47 -0600 Subject: [PATCH] collector/systemd: add new label "type" for systemd_unit_state (#1229) Adds a new label called "type" systemd_unit_state which contains the Type field from the unit file. This applies only to the .service and .mount unit types. The other unit types do not include the optional type field. Fixes #1210 Signed-off-by: Paul Gier --- collector/systemd_linux.go | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/collector/systemd_linux.go b/collector/systemd_linux.go index ac1d0186..b34c938c 100644 --- a/collector/systemd_linux.go +++ b/collector/systemd_linux.go @@ -17,14 +17,14 @@ package collector import ( "fmt" + "math" "regexp" "strings" "github.com/coreos/go-systemd/dbus" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/log" - "gopkg.in/alecthomas/kingpin.v2" - "math" + kingpin "gopkg.in/alecthomas/kingpin.v2" ) var ( @@ -61,7 +61,7 @@ func NewSystemdCollector() (Collector, error) { unitDesc := prometheus.NewDesc( prometheus.BuildFQName(namespace, subsystem, "unit_state"), - "Systemd unit", []string{"name", "state"}, nil, + "Systemd unit", []string{"name", "state", "type"}, nil, ) unitStartTimeDesc := prometheus.NewDesc( prometheus.BuildFQName(namespace, subsystem, "unit_start_time_seconds"), @@ -153,7 +153,7 @@ func (c *systemdCollector) collectUnitStatusMetrics(ch chan<- prometheus.Metric, } ch <- prometheus.MustNewConstMetric( c.unitDesc, prometheus.GaugeValue, isActive, - unit.Name, stateName) + unit.Name, stateName, unit.serviceType) } if strings.HasSuffix(unit.Name, ".service") && unit.nRestarts != nil { ch <- prometheus.MustNewConstMetric( @@ -252,11 +252,22 @@ type unit struct { tasksCurrent *uint64 tasksMax *uint64 nRestarts *uint32 + serviceType string acceptedConnections uint32 currentConnections uint32 refusedConnections *uint32 } +// unitType gets the suffix after the last "." in the +// unit name and capitalizes the first letter +func (u *unit) unitType() string { + suffixIndex := strings.LastIndex(u.Name, ".") + 1 + if suffixIndex < 1 || suffixIndex > len(u.Name) { + return "" + } + return strings.Title(u.Name[suffixIndex:]) +} + func (c *systemdCollector) getAllUnits() ([]unit, error) { conn, err := c.newDbus() if err != nil { @@ -276,7 +287,15 @@ func (c *systemdCollector) getAllUnits() ([]unit, error) { unit := unit{ UnitStatus: status, } - + unitType := unit.unitType() + if unitType == "Service" || unitType == "Mount" { + serviceType, err := conn.GetUnitTypeProperty(unit.Name, unitType, "Type") + if err != nil { + log.Debugf("couldn't get type for unit '%s': %s", unit.Name, err) + } else { + unit.serviceType = serviceType.Value.Value().(string) + } + } if strings.HasSuffix(unit.Name, ".timer") { lastTriggerValue, err := conn.GetUnitTypeProperty(unit.Name, "Timer", "LastTriggerUSec") if err != nil {