diff options
author | Rene Treffer <treffer+github@measite.de> | 2017-06-13 11:21:53 +0200 |
---|---|---|
committer | Johannes 'fish' Ziemke <github@freigeist.org> | 2017-06-13 11:21:53 +0200 |
commit | 2e9f1913b8503d4a287aacef164ec95c971cddeb (patch) | |
tree | a3248c5a6c8ce118a62b087d0f19f53e0750fa2f /collector/stat_linux.go | |
parent | 798950d25b57761b8acb3989eff9e71bbd518846 (diff) | |
download | prometheus_node_collector-2e9f1913b8503d4a287aacef164ec95c971cddeb.tar.bz2 prometheus_node_collector-2e9f1913b8503d4a287aacef164ec95c971cddeb.tar.xz prometheus_node_collector-2e9f1913b8503d4a287aacef164ec95c971cddeb.zip |
Move stat_linux to cpu_linux and add cpufreq stats (#548)
Diffstat (limited to 'collector/stat_linux.go')
-rw-r--r-- | collector/stat_linux.go | 98 |
1 files changed, 19 insertions, 79 deletions
diff --git a/collector/stat_linux.go b/collector/stat_linux.go index 00e1391..5e31108 100644 --- a/collector/stat_linux.go +++ b/collector/stat_linux.go | |||
@@ -16,16 +16,11 @@ | |||
16 | package collector | 16 | package collector |
17 | 17 | ||
18 | import ( | 18 | import ( |
19 | "bufio" | 19 | "fmt" |
20 | "os" | ||
21 | "strconv" | ||
22 | "strings" | ||
23 | 20 | ||
24 | "github.com/prometheus/client_golang/prometheus" | 21 | "github.com/prometheus/procfs" |
25 | ) | ||
26 | 22 | ||
27 | const ( | 23 | "github.com/prometheus/client_golang/prometheus" |
28 | userHz = 100 | ||
29 | ) | 24 | ) |
30 | 25 | ||
31 | type statCollector struct { | 26 | type statCollector struct { |
@@ -83,80 +78,25 @@ func NewStatCollector() (Collector, error) { | |||
83 | }, nil | 78 | }, nil |
84 | } | 79 | } |
85 | 80 | ||
86 | // Expose kernel and system statistics. | 81 | // Update implements Collector and exposes kernel and system statistics. |
87 | func (c *statCollector) Update(ch chan<- prometheus.Metric) error { | 82 | func (c *statCollector) Update(ch chan<- prometheus.Metric) error { |
88 | file, err := os.Open(procFilePath("stat")) | 83 | fs, err := procfs.NewFS(*procPath) |
84 | if err != nil { | ||
85 | return fmt.Errorf("failed to open procfs: %v", err) | ||
86 | } | ||
87 | stats, err := fs.NewStat() | ||
89 | if err != nil { | 88 | if err != nil { |
90 | return err | 89 | return err |
91 | } | 90 | } |
92 | defer file.Close() | ||
93 | 91 | ||
94 | scanner := bufio.NewScanner(file) | 92 | ch <- prometheus.MustNewConstMetric(c.intr, prometheus.CounterValue, float64(stats.IRQTotal)) |
95 | for scanner.Scan() { | 93 | ch <- prometheus.MustNewConstMetric(c.ctxt, prometheus.CounterValue, float64(stats.ContextSwitches)) |
96 | parts := strings.Fields(scanner.Text()) | 94 | ch <- prometheus.MustNewConstMetric(c.forks, prometheus.CounterValue, float64(stats.ProcessCreated)) |
97 | if len(parts) == 0 { | 95 | |
98 | continue | 96 | ch <- prometheus.MustNewConstMetric(c.btime, prometheus.GaugeValue, float64(stats.BootTime)) |
99 | } | 97 | |
100 | switch { | 98 | ch <- prometheus.MustNewConstMetric(c.procsRunning, prometheus.GaugeValue, float64(stats.ProcessesRunning)) |
101 | case strings.HasPrefix(parts[0], "cpu"): | 99 | ch <- prometheus.MustNewConstMetric(c.procsBlocked, prometheus.GaugeValue, float64(stats.ProcessesBlocked)) |
102 | // Export only per-cpu stats, it can be aggregated up in prometheus. | 100 | |
103 | if parts[0] == "cpu" { | 101 | return nil |
104 | break | ||
105 | } | ||
106 | // Only some of these may be present, depending on kernel version. | ||
107 | cpuFields := []string{"user", "nice", "system", "idle", "iowait", "irq", "softirq", "steal", "guest", "guest_nice"} | ||
108 | // OpenVZ guests lack the "guest" CPU field, which needs to be ignored. | ||
109 | expectedFieldNum := len(cpuFields) + 1 | ||
110 | if expectedFieldNum > len(parts) { | ||
111 | expectedFieldNum = len(parts) | ||
112 | } | ||
113 | for i, v := range parts[1:expectedFieldNum] { | ||
114 | value, err := strconv.ParseFloat(v, 64) | ||
115 | if err != nil { | ||
116 | return err | ||
117 | } | ||
118 | // Convert from ticks to seconds | ||
119 | value /= userHz | ||
120 | ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, value, parts[0], cpuFields[i]) | ||
121 | } | ||
122 | case parts[0] == "intr": | ||
123 | // Only expose the overall number, use the 'interrupts' collector for more detail. | ||
124 | value, err := strconv.ParseFloat(parts[1], 64) | ||
125 | if err != nil { | ||
126 | return err | ||
127 | } | ||
128 | ch <- prometheus.MustNewConstMetric(c.intr, prometheus.CounterValue, value) | ||
129 | case parts[0] == "ctxt": | ||
130 | value, err := strconv.ParseFloat(parts[1], 64) | ||
131 | if err != nil { | ||
132 | return err | ||
133 | } | ||
134 | ch <- prometheus.MustNewConstMetric(c.ctxt, prometheus.CounterValue, value) | ||
135 | case parts[0] == "processes": | ||
136 | value, err := strconv.ParseFloat(parts[1], 64) | ||
137 | if err != nil { | ||
138 | return err | ||
139 | } | ||
140 | ch <- prometheus.MustNewConstMetric(c.forks, prometheus.CounterValue, value) | ||
141 | case parts[0] == "btime": | ||
142 | value, err := strconv.ParseFloat(parts[1], 64) | ||
143 | if err != nil { | ||
144 | return err | ||
145 | } | ||
146 | ch <- prometheus.MustNewConstMetric(c.btime, prometheus.GaugeValue, value) | ||
147 | case parts[0] == "procs_running": | ||
148 | value, err := strconv.ParseFloat(parts[1], 64) | ||
149 | if err != nil { | ||
150 | return err | ||
151 | } | ||
152 | ch <- prometheus.MustNewConstMetric(c.procsRunning, prometheus.GaugeValue, value) | ||
153 | case parts[0] == "procs_blocked": | ||
154 | value, err := strconv.ParseFloat(parts[1], 64) | ||
155 | if err != nil { | ||
156 | return err | ||
157 | } | ||
158 | ch <- prometheus.MustNewConstMetric(c.procsBlocked, prometheus.GaugeValue, value) | ||
159 | } | ||
160 | } | ||
161 | return scanner.Err() | ||
162 | } | 102 | } |