This repository has been archived by the owner on Jul 19, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
cpu.go
115 lines (92 loc) · 3.06 KB
/
cpu.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 system
import (
"fmt"
"github.com/influxdb/telegraf/plugins"
"github.com/influxdb/telegraf/plugins/system/ps/cpu"
)
type CPUStats struct {
ps PS
lastStats []cpu.CPUTimesStat
PerCPU bool `toml:"percpu"`
TotalCPU bool `toml:"totalcpu"`
}
func NewCPUStats(ps PS) *CPUStats {
return &CPUStats{
ps: ps,
}
}
func (_ *CPUStats) Description() string {
return "Read metrics about cpu usage"
}
var sampleConfig = `
# Whether to report per-cpu stats or not
percpu = true
# Whether to report total system cpu stats or not
totalcpu = true`
func (_ *CPUStats) SampleConfig() string {
return sampleConfig
}
func (s *CPUStats) Gather(acc plugins.Accumulator) error {
times, err := s.ps.CPUTimes(s.PerCPU, s.TotalCPU)
if err != nil {
return fmt.Errorf("error getting CPU info: %s", err)
}
for i, cts := range times {
tags := map[string]string{
"cpu": cts.CPU,
}
busy, total := busyAndTotalCpuTime(cts)
// Add total cpu numbers
add(acc, "user", cts.User, tags)
add(acc, "system", cts.System, tags)
add(acc, "idle", cts.Idle, tags)
add(acc, "nice", cts.Nice, tags)
add(acc, "iowait", cts.Iowait, tags)
add(acc, "irq", cts.Irq, tags)
add(acc, "softirq", cts.Softirq, tags)
add(acc, "steal", cts.Steal, tags)
add(acc, "guest", cts.Guest, tags)
add(acc, "guestNice", cts.GuestNice, tags)
add(acc, "stolen", cts.Stolen, tags)
add(acc, "busy", busy, tags)
// Add in percentage
if len(s.lastStats) == 0 {
// If it's the 1st gather, can't get CPU stats yet
continue
}
lastCts := s.lastStats[i]
lastBusy, lastTotal := busyAndTotalCpuTime(lastCts)
busyDelta := busy - lastBusy
totalDelta := total - lastTotal
if totalDelta < 0 {
return fmt.Errorf("Error: current total CPU time is less than previous total CPU time")
}
if totalDelta == 0 {
continue
}
add(acc, "percentageUser", 100*(cts.User-lastCts.User)/totalDelta, tags)
add(acc, "percentageSystem", 100*(cts.System-lastCts.System)/totalDelta, tags)
add(acc, "percentageIdle", 100*(cts.Idle-lastCts.Idle)/totalDelta, tags)
add(acc, "percentageNice", 100*(cts.Nice-lastCts.Nice)/totalDelta, tags)
add(acc, "percentageIowait", 100*(cts.Iowait-lastCts.Iowait)/totalDelta, tags)
add(acc, "percentageIrq", 100*(cts.Irq-lastCts.Irq)/totalDelta, tags)
add(acc, "percentageSoftirq", 100*(cts.Softirq-lastCts.Softirq)/totalDelta, tags)
add(acc, "percentageSteal", 100*(cts.Steal-lastCts.Steal)/totalDelta, tags)
add(acc, "percentageGuest", 100*(cts.Guest-lastCts.Guest)/totalDelta, tags)
add(acc, "percentageGuestNice", 100*(cts.GuestNice-lastCts.GuestNice)/totalDelta, tags)
add(acc, "percentageStolen", 100*(cts.Stolen-lastCts.Stolen)/totalDelta, tags)
add(acc, "percentageBusy", 100*busyDelta/totalDelta, tags)
}
s.lastStats = times
return nil
}
func busyAndTotalCpuTime(t cpu.CPUTimesStat) (float64, float64) {
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + t.Softirq + t.Steal +
t.Guest + t.GuestNice + t.Stolen
return busy, busy + t.Idle
}
func init() {
plugins.Add("cpu", func() plugins.Plugin {
return &CPUStats{ps: &systemPS{}}
})
}