master
go 93 lines 2.03 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 //go:build linux
4
5 package systemdunits
6
7 import (
8 "context"
9 "fmt"
10 "strings"
11 "time"
12
13 "github.com/coreos/go-systemd/v22/dbus"
14 )
15
16 // https://github.com/systemd/systemd/blob/3d320785c4bbba74459096b07e85a79c4f0cdffb/src/shared/install.c#L3785
17 // see "is-enabled" in https://www.man7.org/linux/man-pages/man1/systemctl.1.html
18 var unitFileStates = []string{
19 "enabled",
20 "enabled-runtime",
21 "linked",
22 "linked-runtime",
23 "alias",
24 "masked",
25 "masked-runtime",
26 "static",
27 "disabled",
28 "indirect",
29 "generated",
30 "transient",
31 "bad",
32 }
33
34 func (c *Collector) collectUnitFiles(mx map[string]int64, conn systemdConnection) error {
35 if c.systemdVersion < 230 {
36 return nil
37 }
38
39 if now := time.Now(); now.After(c.lastListUnitFilesTime.Add(c.CollectUnitFilesEvery.Duration())) {
40 unitFiles, err := c.getUnitFilesByPatterns(conn)
41 if err != nil {
42 return err
43 }
44 c.lastListUnitFilesTime = now
45 c.cachedUnitFiles = unitFiles
46 }
47
48 seen := make(map[string]bool)
49
50 for _, unitFile := range c.cachedUnitFiles {
51 seen[unitFile.Path] = true
52
53 if !c.seenUnitFiles[unitFile.Path] {
54 c.seenUnitFiles[unitFile.Path] = true
55 c.addUnitFileCharts(unitFile.Path)
56 }
57
58 px := fmt.Sprintf("unit_file_%s_state_", unitFile.Path)
59 for _, st := range unitFileStates {
60 mx[px+st] = 0
61 }
62 mx[px+strings.ToLower(unitFile.Type)] = 1
63 }
64
65 for k := range c.seenUnitFiles {
66 if !seen[k] {
67 delete(c.seenUnitFiles, k)
68 c.removeUnitFileCharts(k)
69 }
70 }
71
72 return nil
73 }
74
75 func (c *Collector) getUnitFilesByPatterns(conn systemdConnection) ([]dbus.UnitFile, error) {
76 ctx, cancel := context.WithTimeout(context.Background(), c.Timeout.Duration())
77 defer cancel()
78
79 c.Debugf("calling function 'ListUnitFilesByPatterns'")
80
81 unitFiles, err := conn.ListUnitFilesByPatternsContext(ctx, nil, c.IncludeUnitFiles)
82 if err != nil {
83 return nil, fmt.Errorf("error on ListUnitFilesByPatterns: %v", err)
84 }
85
86 for i := range unitFiles {
87 unitFiles[i].Path = cleanUnitName(unitFiles[i].Path)
88 }
89
90 c.Debugf("got %d unit files", len(unitFiles))
91
92 return unitFiles, nil
93 }