diff options
author | Phil Frost <indigo@bitglue.com> | 2019-07-10 03:16:24 -0400 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2019-07-10 09:16:24 +0200 |
commit | f693a71c0648ae9dd28f7991ca845afe12539a37 (patch) | |
tree | b925500e78b544632b7085acc23560ded2d49872 /collector/schedstat_linux.go | |
parent | 777b751f9038547ee2367bf145603a8f44967145 (diff) | |
download | prometheus_node_collector-f693a71c0648ae9dd28f7991ca845afe12539a37.tar.bz2 prometheus_node_collector-f693a71c0648ae9dd28f7991ca845afe12539a37.tar.xz prometheus_node_collector-f693a71c0648ae9dd28f7991ca845afe12539a37.zip |
Scrape CPU latency stats from /proc/schedstat (#1389)
These are useful as a direct indication of CPU contention and task
scheduler latency.
Handy references:
- https://github.com/torvalds/linux/blob/master/Documentation/scheduler/sched-stats.txt
- https://doc.opensuse.org/documentation/leap/tuning/html/book.sle.tuning/cha.tuning.taskscheduler.html
procfs is updated to pull in the enabling change:
https://github.com/prometheus/procfs/pull/186
Signed-off-by: Phil Frost <phil@postmates.com>
Diffstat (limited to 'collector/schedstat_linux.go')
-rw-r--r-- | collector/schedstat_linux.go | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/collector/schedstat_linux.go b/collector/schedstat_linux.go new file mode 100644 index 0000000..5e7638a --- /dev/null +++ b/collector/schedstat_linux.go | |||
@@ -0,0 +1,94 @@ | |||
1 | // Copyright 2019 The Prometheus Authors | ||
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
3 | // you may not use this file except in compliance with the License. | ||
4 | // You may obtain a copy of the License at | ||
5 | // | ||
6 | // http://www.apache.org/licenses/LICENSE-2.0 | ||
7 | // | ||
8 | // Unless required by applicable law or agreed to in writing, software | ||
9 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
11 | // See the License for the specific language governing permissions and | ||
12 | // limitations under the License. | ||
13 | |||
14 | package collector | ||
15 | |||
16 | import ( | ||
17 | "fmt" | ||
18 | |||
19 | "github.com/prometheus/client_golang/prometheus" | ||
20 | "github.com/prometheus/procfs" | ||
21 | ) | ||
22 | |||
23 | var ( | ||
24 | runningSecondsTotal = prometheus.NewDesc( | ||
25 | prometheus.BuildFQName(namespace, "schedstat", "running_seconds_total"), | ||
26 | "Number of seconds CPU spent running a process.", | ||
27 | []string{"cpu"}, | ||
28 | nil, | ||
29 | ) | ||
30 | |||
31 | waitingSecondsTotal = prometheus.NewDesc( | ||
32 | prometheus.BuildFQName(namespace, "schedstat", "waiting_seconds_total"), | ||
33 | "Number of seconds spent by processing waiting for this CPU.", | ||
34 | []string{"cpu"}, | ||
35 | nil, | ||
36 | ) | ||
37 | |||
38 | timeslicesTotal = prometheus.NewDesc( | ||
39 | prometheus.BuildFQName(namespace, "schedstat", "timeslices_total"), | ||
40 | "Number of timeslices executed by CPU.", | ||
41 | []string{"cpu"}, | ||
42 | nil, | ||
43 | ) | ||
44 | ) | ||
45 | |||
46 | // NewSchedstatCollector returns a new Collector exposing task scheduler statistics | ||
47 | func NewSchedstatCollector() (Collector, error) { | ||
48 | fs, err := procfs.NewFS(*procPath) | ||
49 | if err != nil { | ||
50 | return nil, fmt.Errorf("failed to open procfs: %v", err) | ||
51 | } | ||
52 | |||
53 | return &schedstatCollector{fs: fs}, nil | ||
54 | } | ||
55 | |||
56 | type schedstatCollector struct { | ||
57 | fs procfs.FS | ||
58 | } | ||
59 | |||
60 | func init() { | ||
61 | registerCollector("schedstat", defaultEnabled, NewSchedstatCollector) | ||
62 | } | ||
63 | |||
64 | func (c *schedstatCollector) Update(ch chan<- prometheus.Metric) error { | ||
65 | stats, err := c.fs.Schedstat() | ||
66 | if err != nil { | ||
67 | return err | ||
68 | } | ||
69 | |||
70 | for _, cpu := range stats.CPUs { | ||
71 | ch <- prometheus.MustNewConstMetric( | ||
72 | runningSecondsTotal, | ||
73 | prometheus.CounterValue, | ||
74 | cpu.RunningSeconds(), | ||
75 | cpu.CPUNum, | ||
76 | ) | ||
77 | |||
78 | ch <- prometheus.MustNewConstMetric( | ||
79 | waitingSecondsTotal, | ||
80 | prometheus.CounterValue, | ||
81 | cpu.WaitingSeconds(), | ||
82 | cpu.CPUNum, | ||
83 | ) | ||
84 | |||
85 | ch <- prometheus.MustNewConstMetric( | ||
86 | timeslicesTotal, | ||
87 | prometheus.CounterValue, | ||
88 | float64(cpu.RunTimeslices), | ||
89 | cpu.CPUNum, | ||
90 | ) | ||
91 | } | ||
92 | |||
93 | return nil | ||
94 | } | ||