/
cpu_poller.go
115 lines (96 loc) · 3.35 KB
/
cpu_poller.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package shh
import (
"strings"
"time"
)
const (
CPU_DATA = "/proc/stat"
)
type CpuValues struct {
User float64
Nice float64
System float64
Idle float64
Iowait float64
Irq float64
Softirq float64
Steal float64
Guest float64
}
func (cv CpuValues) Total() float64 {
return cv.User + cv.Nice + cv.System + cv.Idle + cv.Iowait + cv.Irq + cv.Softirq + cv.Steal + cv.Guest
}
func (cv CpuValues) DiffPercent(last CpuValues) CpuValues {
totalDifference := cv.Total() - last.Total()
if totalDifference == 0 {
return CpuValues{}
}
return CpuValues{
User: (cv.User - last.User) / totalDifference * 100,
Nice: (cv.Nice - last.Nice) / totalDifference * 100,
System: (cv.System - last.System) / totalDifference * 100,
Idle: (cv.Idle - last.Idle) / totalDifference * 100,
Iowait: (cv.Iowait - last.Iowait) / totalDifference * 100,
Irq: (cv.Irq - last.Irq) / totalDifference * 100,
Softirq: (cv.Softirq - last.Softirq) / totalDifference * 100,
Steal: (cv.Steal - last.Steal) / totalDifference * 100,
Guest: (cv.Guest - last.Guest) / totalDifference * 100,
}
}
type Cpu struct {
measurements chan<- Measurement
AggregateOnly bool
last map[string]CpuValues
}
func NewCpuPoller(measurements chan<- Measurement, config Config) Cpu {
return Cpu{
measurements: measurements,
last: make(map[string]CpuValues),
AggregateOnly: config.CpuOnlyAggregate,
}
}
func (poller Cpu) Poll(tick time.Time) {
var current, percent CpuValues
for line := range FileLineChannel(CPU_DATA) {
if strings.HasPrefix(line, "cpu") {
fields := strings.Fields(line)
cpu := fields[0]
if poller.AggregateOnly && cpu != "cpu" {
continue
}
current = CpuValues{
User: Atofloat64(fields[1]),
Nice: Atofloat64(fields[2]),
System: Atofloat64(fields[3]),
Idle: Atofloat64(fields[4]),
Iowait: Atofloat64(fields[5]),
Irq: Atofloat64(fields[6]),
Softirq: Atofloat64(fields[7]),
Steal: Atofloat64(fields[8]),
}
if len(fields) > 9 {
current.Guest = Atofloat64(fields[9])
} else {
current.Guest = 0
}
last, exists := poller.last[cpu]
if exists {
percent = current.DiffPercent(last)
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "user"}, percent.User, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "nice"}, percent.Nice, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "system"}, percent.System, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "idle"}, percent.Idle, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "iowait"}, percent.Iowait, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "irq"}, percent.Irq, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "softirq"}, percent.Softirq, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "steal"}, percent.Steal, Percent}
poller.measurements <- FloatGaugeMeasurement{tick, poller.Name(), []string{cpu, "guest"}, percent.Guest, Percent}
}
poller.last[cpu] = current
}
}
}
func (poller Cpu) Name() string {
return "cpu"
}
func (poller Cpu) Exit() {}