diff options
author | Paul Gier <pgier@redhat.com> | 2019-04-10 11:16:12 -0500 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2019-04-10 18:16:12 +0200 |
commit | b1298677aa13a5f48dd5303120fa4a4bd4579ab9 (patch) | |
tree | a5674890c7713d3d1bd9438a2c3629daa3ca373b | |
parent | fbe390709f5370cd9092233239208fb51f46d15f (diff) | |
download | prometheus_node_collector-b1298677aa13a5f48dd5303120fa4a4bd4579ab9.tar.bz2 prometheus_node_collector-b1298677aa13a5f48dd5303120fa4a4bd4579ab9.tar.xz prometheus_node_collector-b1298677aa13a5f48dd5303120fa4a4bd4579ab9.zip |
Early init of procfs (#1315)
Minor change to match naming convention in other collectors.
Initialize the proc or sys FS instance once while initializing
each collector instead of re-creating for each metric update.
Signed-off-by: Paul Gier <pgier@redhat.com>
-rw-r--r-- | collector/buddyinfo.go | 14 | ||||
-rw-r--r-- | collector/cpu_linux.go | 12 | ||||
-rw-r--r-- | collector/cpufreq_linux.go | 14 | ||||
-rw-r--r-- | collector/ipvs_linux.go | 2 | ||||
-rw-r--r-- | collector/netclass_linux.go | 18 | ||||
-rw-r--r-- | collector/processes_linux.go | 28 | ||||
-rw-r--r-- | collector/processes_linux_test.go | 10 | ||||
-rw-r--r-- | collector/stat_linux.go | 12 |
8 files changed, 63 insertions, 47 deletions
diff --git a/collector/buddyinfo.go b/collector/buddyinfo.go index 72e5f20..9ac790f 100644 --- a/collector/buddyinfo.go +++ b/collector/buddyinfo.go | |||
@@ -30,6 +30,7 @@ const ( | |||
30 | ) | 30 | ) |
31 | 31 | ||
32 | type buddyinfoCollector struct { | 32 | type buddyinfoCollector struct { |
33 | fs procfs.FS | ||
33 | desc *prometheus.Desc | 34 | desc *prometheus.Desc |
34 | } | 35 | } |
35 | 36 | ||
@@ -44,18 +45,17 @@ func NewBuddyinfoCollector() (Collector, error) { | |||
44 | "Count of free blocks according to size.", | 45 | "Count of free blocks according to size.", |
45 | []string{"node", "zone", "size"}, nil, | 46 | []string{"node", "zone", "size"}, nil, |
46 | ) | 47 | ) |
47 | return &buddyinfoCollector{desc}, nil | 48 | fs, err := procfs.NewFS(*procPath) |
49 | if err != nil { | ||
50 | return nil, fmt.Errorf("failed to open procfs: %v", err) | ||
51 | } | ||
52 | return &buddyinfoCollector{fs, desc}, nil | ||
48 | } | 53 | } |
49 | 54 | ||
50 | // Update calls (*buddyinfoCollector).getBuddyInfo to get the platform specific | 55 | // Update calls (*buddyinfoCollector).getBuddyInfo to get the platform specific |
51 | // buddyinfo metrics. | 56 | // buddyinfo metrics. |
52 | func (c *buddyinfoCollector) Update(ch chan<- prometheus.Metric) error { | 57 | func (c *buddyinfoCollector) Update(ch chan<- prometheus.Metric) error { |
53 | fs, err := procfs.NewFS(*procPath) | 58 | buddyInfo, err := c.fs.NewBuddyInfo() |
54 | if err != nil { | ||
55 | return fmt.Errorf("failed to open procfs: %v", err) | ||
56 | } | ||
57 | |||
58 | buddyInfo, err := fs.NewBuddyInfo() | ||
59 | if err != nil { | 59 | if err != nil { |
60 | return fmt.Errorf("couldn't get buddyinfo: %s", err) | 60 | return fmt.Errorf("couldn't get buddyinfo: %s", err) |
61 | } | 61 | } |
diff --git a/collector/cpu_linux.go b/collector/cpu_linux.go index be63590..a8b34db 100644 --- a/collector/cpu_linux.go +++ b/collector/cpu_linux.go | |||
@@ -26,6 +26,7 @@ import ( | |||
26 | ) | 26 | ) |
27 | 27 | ||
28 | type cpuCollector struct { | 28 | type cpuCollector struct { |
29 | fs procfs.FS | ||
29 | cpu *prometheus.Desc | 30 | cpu *prometheus.Desc |
30 | cpuGuest *prometheus.Desc | 31 | cpuGuest *prometheus.Desc |
31 | cpuCoreThrottle *prometheus.Desc | 32 | cpuCoreThrottle *prometheus.Desc |
@@ -38,7 +39,12 @@ func init() { | |||
38 | 39 | ||
39 | // NewCPUCollector returns a new Collector exposing kernel/system statistics. | 40 | // NewCPUCollector returns a new Collector exposing kernel/system statistics. |
40 | func NewCPUCollector() (Collector, error) { | 41 | func NewCPUCollector() (Collector, error) { |
42 | fs, err := procfs.NewFS(*procPath) | ||
43 | if err != nil { | ||
44 | return nil, fmt.Errorf("failed to open procfs: %v", err) | ||
45 | } | ||
41 | return &cpuCollector{ | 46 | return &cpuCollector{ |
47 | fs: fs, | ||
42 | cpu: nodeCPUSecondsDesc, | 48 | cpu: nodeCPUSecondsDesc, |
43 | cpuGuest: prometheus.NewDesc( | 49 | cpuGuest: prometheus.NewDesc( |
44 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "guest_seconds_total"), | 50 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "guest_seconds_total"), |
@@ -149,11 +155,7 @@ func (c *cpuCollector) updateThermalThrottle(ch chan<- prometheus.Metric) error | |||
149 | 155 | ||
150 | // updateStat reads /proc/stat through procfs and exports cpu related metrics. | 156 | // updateStat reads /proc/stat through procfs and exports cpu related metrics. |
151 | func (c *cpuCollector) updateStat(ch chan<- prometheus.Metric) error { | 157 | func (c *cpuCollector) updateStat(ch chan<- prometheus.Metric) error { |
152 | fs, err := procfs.NewFS(*procPath) | 158 | stats, err := c.fs.NewStat() |
153 | if err != nil { | ||
154 | return fmt.Errorf("failed to open procfs: %v", err) | ||
155 | } | ||
156 | stats, err := fs.NewStat() | ||
157 | if err != nil { | 159 | if err != nil { |
158 | return err | 160 | return err |
159 | } | 161 | } |
diff --git a/collector/cpufreq_linux.go b/collector/cpufreq_linux.go index 11f6f38..badc16f 100644 --- a/collector/cpufreq_linux.go +++ b/collector/cpufreq_linux.go | |||
@@ -23,6 +23,7 @@ import ( | |||
23 | ) | 23 | ) |
24 | 24 | ||
25 | type cpuFreqCollector struct { | 25 | type cpuFreqCollector struct { |
26 | fs sysfs.FS | ||
26 | cpuFreq *prometheus.Desc | 27 | cpuFreq *prometheus.Desc |
27 | cpuFreqMin *prometheus.Desc | 28 | cpuFreqMin *prometheus.Desc |
28 | cpuFreqMax *prometheus.Desc | 29 | cpuFreqMax *prometheus.Desc |
@@ -37,7 +38,13 @@ func init() { | |||
37 | 38 | ||
38 | // NewCPUFreqCollector returns a new Collector exposing kernel/system statistics. | 39 | // NewCPUFreqCollector returns a new Collector exposing kernel/system statistics. |
39 | func NewCPUFreqCollector() (Collector, error) { | 40 | func NewCPUFreqCollector() (Collector, error) { |
41 | fs, err := sysfs.NewFS(*sysPath) | ||
42 | if err != nil { | ||
43 | return nil, fmt.Errorf("failed to open sysfs: %v", err) | ||
44 | } | ||
45 | |||
40 | return &cpuFreqCollector{ | 46 | return &cpuFreqCollector{ |
47 | fs: fs, | ||
41 | cpuFreq: prometheus.NewDesc( | 48 | cpuFreq: prometheus.NewDesc( |
42 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_hertz"), | 49 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_hertz"), |
43 | "Current cpu thread frequency in hertz.", | 50 | "Current cpu thread frequency in hertz.", |
@@ -73,12 +80,7 @@ func NewCPUFreqCollector() (Collector, error) { | |||
73 | 80 | ||
74 | // Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/. | 81 | // Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/. |
75 | func (c *cpuFreqCollector) Update(ch chan<- prometheus.Metric) error { | 82 | func (c *cpuFreqCollector) Update(ch chan<- prometheus.Metric) error { |
76 | fs, err := sysfs.NewFS(*sysPath) | 83 | cpuFreqs, err := c.fs.NewSystemCpufreq() |
77 | if err != nil { | ||
78 | return fmt.Errorf("failed to open sysfs: %v", err) | ||
79 | } | ||
80 | |||
81 | cpuFreqs, err := fs.NewSystemCpufreq() | ||
82 | if err != nil { | 84 | if err != nil { |
83 | return err | 85 | return err |
84 | } | 86 | } |
diff --git a/collector/ipvs_linux.go b/collector/ipvs_linux.go index 3739193..524bac4 100644 --- a/collector/ipvs_linux.go +++ b/collector/ipvs_linux.go | |||
@@ -58,7 +58,7 @@ func newIPVSCollector() (*ipvsCollector, error) { | |||
58 | 58 | ||
59 | c.fs, err = procfs.NewFS(*procPath) | 59 | c.fs, err = procfs.NewFS(*procPath) |
60 | if err != nil { | 60 | if err != nil { |
61 | return nil, err | 61 | return nil, fmt.Errorf("failed to open procfs: %v", err) |
62 | } | 62 | } |
63 | 63 | ||
64 | c.connections = typedDesc{prometheus.NewDesc( | 64 | c.connections = typedDesc{prometheus.NewDesc( |
diff --git a/collector/netclass_linux.go b/collector/netclass_linux.go index d70db58..d02ead6 100644 --- a/collector/netclass_linux.go +++ b/collector/netclass_linux.go | |||
@@ -30,6 +30,7 @@ var ( | |||
30 | ) | 30 | ) |
31 | 31 | ||
32 | type netClassCollector struct { | 32 | type netClassCollector struct { |
33 | fs sysfs.FS | ||
33 | subsystem string | 34 | subsystem string |
34 | ignoredDevicesPattern *regexp.Regexp | 35 | ignoredDevicesPattern *regexp.Regexp |
35 | metricDescs map[string]*prometheus.Desc | 36 | metricDescs map[string]*prometheus.Desc |
@@ -41,8 +42,13 @@ func init() { | |||
41 | 42 | ||
42 | // NewNetClassCollector returns a new Collector exposing network class stats. | 43 | // NewNetClassCollector returns a new Collector exposing network class stats. |
43 | func NewNetClassCollector() (Collector, error) { | 44 | func NewNetClassCollector() (Collector, error) { |
45 | fs, err := sysfs.NewFS(*sysPath) | ||
46 | if err != nil { | ||
47 | return nil, fmt.Errorf("failed to open sysfs: %v", err) | ||
48 | } | ||
44 | pattern := regexp.MustCompile(*netclassIgnoredDevices) | 49 | pattern := regexp.MustCompile(*netclassIgnoredDevices) |
45 | return &netClassCollector{ | 50 | return &netClassCollector{ |
51 | fs: fs, | ||
46 | subsystem: "network", | 52 | subsystem: "network", |
47 | ignoredDevicesPattern: pattern, | 53 | ignoredDevicesPattern: pattern, |
48 | metricDescs: map[string]*prometheus.Desc{}, | 54 | metricDescs: map[string]*prometheus.Desc{}, |
@@ -50,7 +56,7 @@ func NewNetClassCollector() (Collector, error) { | |||
50 | } | 56 | } |
51 | 57 | ||
52 | func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error { | 58 | func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error { |
53 | netClass, err := getNetClassInfo(c.ignoredDevicesPattern) | 59 | netClass, err := c.getNetClassInfo() |
54 | if err != nil { | 60 | if err != nil { |
55 | return fmt.Errorf("could not get net class info: %s", err) | 61 | return fmt.Errorf("could not get net class info: %s", err) |
56 | } | 62 | } |
@@ -162,19 +168,15 @@ func pushMetric(ch chan<- prometheus.Metric, subsystem string, name string, valu | |||
162 | ch <- prometheus.MustNewConstMetric(fieldDesc, valueType, float64(value), ifaceName) | 168 | ch <- prometheus.MustNewConstMetric(fieldDesc, valueType, float64(value), ifaceName) |
163 | } | 169 | } |
164 | 170 | ||
165 | func getNetClassInfo(ignore *regexp.Regexp) (sysfs.NetClass, error) { | 171 | func (c *netClassCollector) getNetClassInfo() (sysfs.NetClass, error) { |
166 | fs, err := sysfs.NewFS(*sysPath) | 172 | netClass, err := c.fs.NewNetClass() |
167 | if err != nil { | ||
168 | return nil, err | ||
169 | } | ||
170 | netClass, err := fs.NewNetClass() | ||
171 | 173 | ||
172 | if err != nil { | 174 | if err != nil { |
173 | return netClass, fmt.Errorf("error obtaining net class info: %s", err) | 175 | return netClass, fmt.Errorf("error obtaining net class info: %s", err) |
174 | } | 176 | } |
175 | 177 | ||
176 | for device := range netClass { | 178 | for device := range netClass { |
177 | if ignore.MatchString(device) { | 179 | if c.ignoredDevicesPattern.MatchString(device) { |
178 | delete(netClass, device) | 180 | delete(netClass, device) |
179 | } | 181 | } |
180 | } | 182 | } |
diff --git a/collector/processes_linux.go b/collector/processes_linux.go index f321560..1ee012e 100644 --- a/collector/processes_linux.go +++ b/collector/processes_linux.go | |||
@@ -25,6 +25,7 @@ import ( | |||
25 | ) | 25 | ) |
26 | 26 | ||
27 | type processCollector struct { | 27 | type processCollector struct { |
28 | fs procfs.FS | ||
28 | threadAlloc *prometheus.Desc | 29 | threadAlloc *prometheus.Desc |
29 | threadLimit *prometheus.Desc | 30 | threadLimit *prometheus.Desc |
30 | procsState *prometheus.Desc | 31 | procsState *prometheus.Desc |
@@ -38,8 +39,13 @@ func init() { | |||
38 | 39 | ||
39 | // NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem. | 40 | // NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem. |
40 | func NewProcessStatCollector() (Collector, error) { | 41 | func NewProcessStatCollector() (Collector, error) { |
42 | fs, err := procfs.NewFS(*procPath) | ||
43 | if err != nil { | ||
44 | return nil, fmt.Errorf("failed to open procfs: %v", err) | ||
45 | } | ||
41 | subsystem := "processes" | 46 | subsystem := "processes" |
42 | return &processCollector{ | 47 | return &processCollector{ |
48 | fs: fs, | ||
43 | threadAlloc: prometheus.NewDesc( | 49 | threadAlloc: prometheus.NewDesc( |
44 | prometheus.BuildFQName(namespace, subsystem, "threads"), | 50 | prometheus.BuildFQName(namespace, subsystem, "threads"), |
45 | "Allocated threads in system", | 51 | "Allocated threads in system", |
@@ -63,39 +69,35 @@ func NewProcessStatCollector() (Collector, error) { | |||
63 | ), | 69 | ), |
64 | }, nil | 70 | }, nil |
65 | } | 71 | } |
66 | func (t *processCollector) Update(ch chan<- prometheus.Metric) error { | 72 | func (c *processCollector) Update(ch chan<- prometheus.Metric) error { |
67 | pids, states, threads, err := getAllocatedThreads() | 73 | pids, states, threads, err := c.getAllocatedThreads() |
68 | if err != nil { | 74 | if err != nil { |
69 | return fmt.Errorf("unable to retrieve number of allocated threads: %q", err) | 75 | return fmt.Errorf("unable to retrieve number of allocated threads: %q", err) |
70 | } | 76 | } |
71 | 77 | ||
72 | ch <- prometheus.MustNewConstMetric(t.threadAlloc, prometheus.GaugeValue, float64(threads)) | 78 | ch <- prometheus.MustNewConstMetric(c.threadAlloc, prometheus.GaugeValue, float64(threads)) |
73 | maxThreads, err := readUintFromFile(procFilePath("sys/kernel/threads-max")) | 79 | maxThreads, err := readUintFromFile(procFilePath("sys/kernel/threads-max")) |
74 | if err != nil { | 80 | if err != nil { |
75 | return fmt.Errorf("unable to retrieve limit number of threads: %q", err) | 81 | return fmt.Errorf("unable to retrieve limit number of threads: %q", err) |
76 | } | 82 | } |
77 | ch <- prometheus.MustNewConstMetric(t.threadLimit, prometheus.GaugeValue, float64(maxThreads)) | 83 | ch <- prometheus.MustNewConstMetric(c.threadLimit, prometheus.GaugeValue, float64(maxThreads)) |
78 | 84 | ||
79 | for state := range states { | 85 | for state := range states { |
80 | ch <- prometheus.MustNewConstMetric(t.procsState, prometheus.GaugeValue, float64(states[state]), state) | 86 | ch <- prometheus.MustNewConstMetric(c.procsState, prometheus.GaugeValue, float64(states[state]), state) |
81 | } | 87 | } |
82 | 88 | ||
83 | pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max")) | 89 | pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max")) |
84 | if err != nil { | 90 | if err != nil { |
85 | return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %q", err) | 91 | return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %q", err) |
86 | } | 92 | } |
87 | ch <- prometheus.MustNewConstMetric(t.pidUsed, prometheus.GaugeValue, float64(pids)) | 93 | ch <- prometheus.MustNewConstMetric(c.pidUsed, prometheus.GaugeValue, float64(pids)) |
88 | ch <- prometheus.MustNewConstMetric(t.pidMax, prometheus.GaugeValue, float64(pidM)) | 94 | ch <- prometheus.MustNewConstMetric(c.pidMax, prometheus.GaugeValue, float64(pidM)) |
89 | 95 | ||
90 | return nil | 96 | return nil |
91 | } | 97 | } |
92 | 98 | ||
93 | func getAllocatedThreads() (int, map[string]int32, int, error) { | 99 | func (c *processCollector) getAllocatedThreads() (int, map[string]int32, int, error) { |
94 | fs, err := procfs.NewFS(*procPath) | 100 | p, err := c.fs.AllProcs() |
95 | if err != nil { | ||
96 | return 0, nil, 0, err | ||
97 | } | ||
98 | p, err := fs.AllProcs() | ||
99 | if err != nil { | 101 | if err != nil { |
100 | return 0, nil, 0, err | 102 | return 0, nil, 0, err |
101 | } | 103 | } |
diff --git a/collector/processes_linux_test.go b/collector/processes_linux_test.go index 1cf9e4f..dc71ced 100644 --- a/collector/processes_linux_test.go +++ b/collector/processes_linux_test.go | |||
@@ -18,7 +18,8 @@ package collector | |||
18 | import ( | 18 | import ( |
19 | "testing" | 19 | "testing" |
20 | 20 | ||
21 | "gopkg.in/alecthomas/kingpin.v2" | 21 | "github.com/prometheus/procfs" |
22 | kingpin "gopkg.in/alecthomas/kingpin.v2" | ||
22 | ) | 23 | ) |
23 | 24 | ||
24 | func TestReadProcessStatus(t *testing.T) { | 25 | func TestReadProcessStatus(t *testing.T) { |
@@ -26,7 +27,12 @@ func TestReadProcessStatus(t *testing.T) { | |||
26 | t.Fatal(err) | 27 | t.Fatal(err) |
27 | } | 28 | } |
28 | want := 1 | 29 | want := 1 |
29 | pids, states, threads, err := getAllocatedThreads() | 30 | fs, err := procfs.NewFS(*procPath) |
31 | if err != nil { | ||
32 | t.Errorf("failed to open procfs: %v", err) | ||
33 | } | ||
34 | c := processCollector{fs: fs} | ||
35 | pids, states, threads, err := c.getAllocatedThreads() | ||
30 | if err != nil { | 36 | if err != nil { |
31 | t.Fatalf("Cannot retrieve data from procfs getAllocatedThreads function: %v ", err) | 37 | t.Fatalf("Cannot retrieve data from procfs getAllocatedThreads function: %v ", err) |
32 | } | 38 | } |
diff --git a/collector/stat_linux.go b/collector/stat_linux.go index 290205f..13a4b01 100644 --- a/collector/stat_linux.go +++ b/collector/stat_linux.go | |||
@@ -24,6 +24,7 @@ import ( | |||
24 | ) | 24 | ) |
25 | 25 | ||
26 | type statCollector struct { | 26 | type statCollector struct { |
27 | fs procfs.FS | ||
27 | intr *prometheus.Desc | 28 | intr *prometheus.Desc |
28 | ctxt *prometheus.Desc | 29 | ctxt *prometheus.Desc |
29 | forks *prometheus.Desc | 30 | forks *prometheus.Desc |
@@ -38,7 +39,12 @@ func init() { | |||
38 | 39 | ||
39 | // NewStatCollector returns a new Collector exposing kernel/system statistics. | 40 | // NewStatCollector returns a new Collector exposing kernel/system statistics. |
40 | func NewStatCollector() (Collector, error) { | 41 | func NewStatCollector() (Collector, error) { |
42 | fs, err := procfs.NewFS(*procPath) | ||
43 | if err != nil { | ||
44 | return nil, fmt.Errorf("failed to open procfs: %v", err) | ||
45 | } | ||
41 | return &statCollector{ | 46 | return &statCollector{ |
47 | fs: fs, | ||
42 | intr: prometheus.NewDesc( | 48 | intr: prometheus.NewDesc( |
43 | prometheus.BuildFQName(namespace, "", "intr_total"), | 49 | prometheus.BuildFQName(namespace, "", "intr_total"), |
44 | "Total number of interrupts serviced.", | 50 | "Total number of interrupts serviced.", |
@@ -74,11 +80,7 @@ func NewStatCollector() (Collector, error) { | |||
74 | 80 | ||
75 | // Update implements Collector and exposes kernel and system statistics. | 81 | // Update implements Collector and exposes kernel and system statistics. |
76 | func (c *statCollector) Update(ch chan<- prometheus.Metric) error { | 82 | func (c *statCollector) Update(ch chan<- prometheus.Metric) error { |
77 | fs, err := procfs.NewFS(*procPath) | 83 | stats, err := c.fs.NewStat() |
78 | if err != nil { | ||
79 | return fmt.Errorf("failed to open procfs: %v", err) | ||
80 | } | ||
81 | stats, err := fs.NewStat() | ||
82 | if err != nil { | 84 | if err != nil { |
83 | return err | 85 | return err |
84 | } | 86 | } |