@@ -12,10 +12,14 @@ import (
12
12
)
13
13
14
14
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"
19
23
)
20
24
21
25
// ContainerCPU returns the CPU usage of the container cgroup.
@@ -57,7 +61,7 @@ func (s *Statter) cgroupCPU() (used, total time.Duration, err error) {
57
61
58
62
func (s * Statter ) isCGroupV2 () bool {
59
63
// 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 )
61
65
return err == nil
62
66
}
63
67
@@ -178,7 +182,11 @@ func (s *Statter) cgroupV1CPUUsed() (time.Duration, error) {
178
182
179
183
data , err = afero .ReadFile (s .fs , cgroupV1CPUAcctUsage )
180
184
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
+ }
182
190
}
183
191
184
192
usageUs , err = strconv .ParseInt (string (bytes .TrimSpace (data )), 10 , 64 )
@@ -209,7 +217,61 @@ func (*Statter) cGroupv2Memory() (*Result, error) {
209
217
return nil , nil
210
218
}
211
219
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
215
277
}
0 commit comments