Skip to content

Commit fa0c4c6

Browse files
committed
cgroupv1 memory
1 parent 495b5b0 commit fa0c4c6

File tree

1 file changed

+71
-9
lines changed

1 file changed

+71
-9
lines changed

cli/clistat/cgroup.go

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ import (
1212
)
1313

1414
const (
15-
cgroupV1CPUAcctUsage = "/sys/fs/cgroup/cpu,cpuacct/cpuacct.usage"
16-
cgroupV1CFSQuotaUs = "/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us"
17-
cgroupV2CPUMax = "/sys/fs/cgroup/cpu.max"
18-
cgroupV2CPUStat = "/sys/fs/cgroup/cpu.stat"
15+
cgroupV1CPUAcctUsage = "/sys/fs/cgroup/cpu/cpuacct.usage"
16+
cgroupV1CPUAcctUsageAlt = "/sys/fs/cgroup/cpu,cpuacct/cpuacct.usage"
17+
cgroupV1CFSQuotaUs = "/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us"
18+
cgroupV1MemoryMaxUsageBytes = "/sys/fs/cgroup/memory/memory.max_usage_in_bytes"
19+
cgroupV1MemoryUsageBytes = "/sys/fs/cgroup/memory/memory.usage_in_bytes"
20+
cgroupV1MemoryStat = "/sys/fs/cgroup/memory/memory.stat"
21+
cgroupV2CPUMax = "/sys/fs/cgroup/cpu.max"
22+
cgroupV2CPUStat = "/sys/fs/cgroup/cpu.stat"
1923
)
2024

2125
// ContainerCPU returns the CPU usage of the container cgroup.
@@ -57,7 +61,7 @@ func (s *Statter) cgroupCPU() (used, total time.Duration, err error) {
5761

5862
func (s *Statter) isCGroupV2() bool {
5963
// Check for the presence of /sys/fs/cgroup/cpu.max
60-
_, err := s.fs.Stat("/sys/fs/cgroup/cpu.max")
64+
_, err := s.fs.Stat(cgroupV2CPUMax)
6165
return err == nil
6266
}
6367

@@ -178,7 +182,11 @@ func (s *Statter) cgroupV1CPUUsed() (time.Duration, error) {
178182

179183
data, err = afero.ReadFile(s.fs, cgroupV1CPUAcctUsage)
180184
if err != nil {
181-
return 0, xerrors.Errorf("read %s: %w", cgroupV1CPUAcctUsage, err)
185+
// try alternate path
186+
data, err = afero.ReadFile(s.fs, cgroupV1CPUAcctUsageAlt)
187+
if err != nil {
188+
return 0, xerrors.Errorf("read %s or %s: %w", cgroupV1CPUAcctUsage, cgroupV1CPUAcctUsageAlt, err)
189+
}
182190
}
183191

184192
usageUs, err = strconv.ParseInt(string(bytes.TrimSpace(data)), 10, 64)
@@ -209,7 +217,61 @@ func (*Statter) cGroupv2Memory() (*Result, error) {
209217
return nil, nil
210218
}
211219

212-
func (*Statter) cGroupv1Memory() (*Result, error) {
213-
// TODO implement
214-
return nil, nil
220+
func (s *Statter) cGroupv1Memory() (*Result, error) {
221+
var data []byte
222+
var err error
223+
var usageBytes int64
224+
var maxUsageBytes int64
225+
var totalInactiveFileBytes int64
226+
227+
// Read max memory usage
228+
data, err = afero.ReadFile(s.fs, cgroupV1MemoryMaxUsageBytes)
229+
if err != nil {
230+
return nil, xerrors.Errorf("read %s: %w", cgroupV1MemoryMaxUsageBytes, err)
231+
}
232+
233+
maxUsageBytes, err = strconv.ParseInt(string(bytes.TrimSpace(data)), 10, 64)
234+
if err != nil {
235+
return nil, xerrors.Errorf("parse %s: %w", cgroupV1MemoryMaxUsageBytes, err)
236+
}
237+
238+
// Read current memory usage
239+
data, err = afero.ReadFile(s.fs, cgroupV1MemoryUsageBytes)
240+
if err != nil {
241+
return nil, xerrors.Errorf("read %s: %w", cgroupV1MemoryUsageBytes, err)
242+
}
243+
244+
usageBytes, err = strconv.ParseInt(string(bytes.TrimSpace(data)), 10, 64)
245+
if err != nil {
246+
return nil, xerrors.Errorf("parse %s: %w", cgroupV1MemoryUsageBytes, err)
247+
}
248+
249+
// Get total_inactive_file from memory.stat
250+
data, err = afero.ReadFile(s.fs, cgroupV1MemoryStat)
251+
if err != nil {
252+
return nil, xerrors.Errorf("read %s: %w", cgroupV1MemoryStat, err)
253+
}
254+
scn := bufio.NewScanner(bytes.NewReader(data))
255+
for scn.Scan() {
256+
line := scn.Bytes()
257+
if !bytes.HasPrefix(line, []byte("total_inactive_file")) {
258+
continue
259+
}
260+
261+
parts := bytes.Split(line, []byte(" "))
262+
if len(parts) != 2 {
263+
return nil, xerrors.Errorf("unexpected value in %s: %s", cgroupV1MemoryUsageBytes, string(line))
264+
}
265+
totalInactiveFileBytes, err = strconv.ParseInt(string(bytes.TrimSpace(parts[1])), 10, 64)
266+
if err != nil {
267+
return nil, xerrors.Errorf("parse %s: %w", cgroupV1MemoryUsageBytes, err)
268+
}
269+
}
270+
271+
// Total memory used is usage - total_inactive_file
272+
return &Result{
273+
Total: ptr.To(float64(maxUsageBytes) / 1024 / 1024 / 1024),
274+
Used: float64(usageBytes-totalInactiveFileBytes) / 1024 / 1024 / 1024,
275+
Unit: "GB",
276+
}, nil
215277
}

0 commit comments

Comments
 (0)