Adding socket stat collection for systemd socket units (#968)

Signed-off-by: xginn8 <mamcgi@gmail.com>
This commit is contained in:
xginn8 2018-07-05 10:26:48 -04:00 committed by Ben Kochie
parent 8af84a215d
commit ac5a981761
3 changed files with 63 additions and 16 deletions

View file

@ -4,6 +4,7 @@
* [CHANGE] * [CHANGE]
* [FEATURE] Collect NRestarts property for systemd service units * [FEATURE] Collect NRestarts property for systemd service units
* [FEATURE] Add socket unit stats to systemd collector #968
* [ENHANCEMENT] * [ENHANCEMENT]
* [BUGFIX] * [BUGFIX]

View file

@ -33,13 +33,15 @@ var (
) )
type systemdCollector struct { type systemdCollector struct {
unitDesc *prometheus.Desc unitDesc *prometheus.Desc
systemRunningDesc *prometheus.Desc systemRunningDesc *prometheus.Desc
summaryDesc *prometheus.Desc summaryDesc *prometheus.Desc
nRestartsDesc *prometheus.Desc nRestartsDesc *prometheus.Desc
timerLastTriggerDesc *prometheus.Desc timerLastTriggerDesc *prometheus.Desc
unitWhitelistPattern *regexp.Regexp socketAcceptedConnectionsDesc *prometheus.Desc
unitBlacklistPattern *regexp.Regexp socketCurrentConnectionsDesc *prometheus.Desc
unitWhitelistPattern *regexp.Regexp
unitBlacklistPattern *regexp.Regexp
} }
var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"} var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"}
@ -70,17 +72,25 @@ func NewSystemdCollector() (Collector, error) {
timerLastTriggerDesc := prometheus.NewDesc( timerLastTriggerDesc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "timer_last_trigger_seconds"), prometheus.BuildFQName(namespace, subsystem, "timer_last_trigger_seconds"),
"Seconds since epoch of last trigger.", []string{"name"}, nil) "Seconds since epoch of last trigger.", []string{"name"}, nil)
socketAcceptedConnectionsDesc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "socket_accepted_connections_total"),
"Total number of accepted socket connections", []string{"name"}, nil)
socketCurrentConnectionsDesc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "socket_current_connections"),
"Current number of socket connections", []string{"name"}, 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))
return &systemdCollector{ return &systemdCollector{
unitDesc: unitDesc, unitDesc: unitDesc,
systemRunningDesc: systemRunningDesc, systemRunningDesc: systemRunningDesc,
summaryDesc: summaryDesc, summaryDesc: summaryDesc,
nRestartsDesc: nRestartsDesc, nRestartsDesc: nRestartsDesc,
timerLastTriggerDesc: timerLastTriggerDesc, timerLastTriggerDesc: timerLastTriggerDesc,
unitWhitelistPattern: unitWhitelistPattern, socketAcceptedConnectionsDesc: socketAcceptedConnectionsDesc,
unitBlacklistPattern: unitBlacklistPattern, socketCurrentConnectionsDesc: socketCurrentConnectionsDesc,
unitWhitelistPattern: unitWhitelistPattern,
unitBlacklistPattern: unitBlacklistPattern,
}, nil }, nil
} }
@ -96,6 +106,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
units := filterUnits(allUnits, c.unitWhitelistPattern, c.unitBlacklistPattern) units := filterUnits(allUnits, c.unitWhitelistPattern, c.unitBlacklistPattern)
c.collectUnitStatusMetrics(ch, units) c.collectUnitStatusMetrics(ch, units)
c.collectTimers(ch, units) c.collectTimers(ch, units)
c.collectSockets(ch, units)
systemState, err := c.getSystemState() systemState, err := c.getSystemState()
if err != nil { if err != nil {
@ -125,6 +136,22 @@ func (c *systemdCollector) collectUnitStatusMetrics(ch chan<- prometheus.Metric,
} }
} }
func (c *systemdCollector) collectSockets(ch chan<- prometheus.Metric, units []unit) error {
for _, unit := range units {
if !strings.HasSuffix(unit.Name, ".socket") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.socketAcceptedConnectionsDesc, prometheus.CounterValue,
float64(unit.acceptedConnections), unit.Name)
ch <- prometheus.MustNewConstMetric(
c.socketCurrentConnectionsDesc, prometheus.GaugeValue,
float64(unit.currentConnections), unit.Name)
}
return nil
}
func (c *systemdCollector) collectTimers(ch chan<- prometheus.Metric, units []unit) error { func (c *systemdCollector) collectTimers(ch chan<- prometheus.Metric, units []unit) error {
for _, unit := range units { for _, unit := range units {
if !strings.HasSuffix(unit.Name, ".timer") { if !strings.HasSuffix(unit.Name, ".timer") {
@ -162,8 +189,10 @@ func (c *systemdCollector) newDbus() (*dbus.Conn, error) {
type unit struct { type unit struct {
dbus.UnitStatus dbus.UnitStatus
lastTriggerUsec uint64 lastTriggerUsec uint64
nRestarts uint32 nRestarts uint32
acceptedConnections uint32
currentConnections uint32
} }
func (c *systemdCollector) getAllUnits() ([]unit, error) { func (c *systemdCollector) getAllUnits() ([]unit, error) {
@ -201,6 +230,22 @@ func (c *systemdCollector) getAllUnits() ([]unit, error) {
unit.nRestarts = nRestarts.Value.Value().(uint32) unit.nRestarts = nRestarts.Value.Value().(uint32)
} }
if strings.HasSuffix(unit.Name, ".socket") {
acceptedConnectionCount, err := conn.GetUnitTypeProperty(unit.Name, "Socket", "NAccepted")
if err != nil {
return nil, fmt.Errorf("couldn't get unit '%s' NAccepted: %s", unit.Name, err)
}
unit.acceptedConnections = acceptedConnectionCount.Value.Value().(uint32)
currentConnectionCount, err := conn.GetUnitTypeProperty(unit.Name, "Socket", "NConnections")
if err != nil {
return nil, fmt.Errorf("couldn't get unit '%s' NConnections: %s", unit.Name, err)
}
unit.currentConnections = currentConnectionCount.Value.Value().(uint32)
}
result = append(result, unit) result = append(result, unit)
} }

View file

@ -103,6 +103,7 @@ func TestSystemdCollectorDoesntCrash(t *testing.T) {
collector := (c).(*systemdCollector) collector := (c).(*systemdCollector)
for _, units := range fixtures { for _, units := range fixtures {
collector.collectUnitStatusMetrics(sink, units) collector.collectUnitStatusMetrics(sink, units)
collector.collectSockets(sink, units)
} }
} }