forked from elastic/gosigar
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cpu.go
139 lines (118 loc) · 3.55 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package cgroup
import (
"bufio"
"os"
"path/filepath"
)
// CPUSubsystem contains metrics and limits from the "cpu" subsystem. This
// subsystem is used to guarantee a minimum number of cpu shares to the cgroup
// when the system is busy. This subsystem does not track CPU usage, for that
// information see the "cpuacct" subsystem.
type CPUSubsystem struct {
Metadata
// Completely Fair Scheduler (CFS) settings.
CFS CFS `json:"cfs,omitempty"`
// Real-time (RT) Scheduler settings.
RT RT `json:"rt,omitempty"`
// CPU time statistics for tasks in this cgroup.
Stats ThrottleStats `json:"stats,omitempty"`
}
// RT contains the tunable parameters for the real-time scheduler.
type RT struct {
// Period of time in microseconds for how regularly the cgroup's access to
// CPU resources should be reallocated.
PeriodMicros uint64 `json:"period_us"`
// Period of time in microseconds for the longest continuous period in which
// the tasks in the cgroup have access to CPU resources.
RuntimeMicros uint64 `json:"quota_us"`
}
// CFS contains the tunable parameters for the completely fair scheduler.
type CFS struct {
// Period of time in microseconds for how regularly the cgroup's access to
// CPU resources should be reallocated.
PeriodMicros uint64 `json:"period_us"`
// Total amount of time in microseconds for which all tasks in the cgroup
// can run during one period.
QuotaMicros uint64 `json:"quota_us"`
// Relative share of CPU time available to tasks the cgroup. The value is
// an integer greater than or equal to 2.
Shares uint64 `json:"shares"`
}
// ThrottleStats contains stats that indicate the extent to which this cgroup's
// CPU usage was throttled.
type ThrottleStats struct {
// Number of periods with throttling active.
Periods uint64 `json:"periods,omitempty"`
// Number of periods when the cgroup hit its throttling limit.
ThrottledPeriods uint64 `json:"throttled_periods,omitempty"`
// Aggregate time the cgroup was throttled for in nanoseconds.
ThrottledTimeNanos uint64 `json:"throttled_nanos,omitempty"`
}
// get reads metrics from the "cpu" subsystem. path is the filepath to the
// cgroup hierarchy to read.
func (cpu *CPUSubsystem) get(path string) error {
if err := cpuCFS(path, cpu); err != nil {
return err
}
if err := cpuRT(path, cpu); err != nil {
return err
}
if err := cpuStat(path, cpu); err != nil {
return err
}
return nil
}
func cpuStat(path string, cpu *CPUSubsystem) error {
f, err := os.Open(filepath.Join(path, "cpu.stat"))
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
defer f.Close()
sc := bufio.NewScanner(f)
for sc.Scan() {
t, v, err := parseCgroupParamKeyValue(sc.Text())
if err != nil {
return err
}
switch t {
case "nr_periods":
cpu.Stats.Periods = v
case "nr_throttled":
cpu.Stats.ThrottledPeriods = v
case "throttled_time":
cpu.Stats.ThrottledTimeNanos = v
}
}
return sc.Err()
}
func cpuCFS(path string, cpu *CPUSubsystem) error {
var err error
cpu.CFS.PeriodMicros, err = parseUintFromFile(path, "cpu.cfs_period_us")
if err != nil {
return err
}
cpu.CFS.QuotaMicros, err = parseUintFromFile(path, "cpu.cfs_quota_us")
if err != nil {
return err
}
cpu.CFS.Shares, err = parseUintFromFile(path, "cpu.shares")
if err != nil {
return err
}
return nil
}
func cpuRT(path string, cpu *CPUSubsystem) error {
var err error
cpu.RT.PeriodMicros, err = parseUintFromFile(path, "cpu.rt_period_us")
if err != nil {
return err
}
cpu.RT.RuntimeMicros, err = parseUintFromFile(path, "cpu.rt_runtime_us")
if err != nil {
return err
}
return nil
}