33package fs
44
55import (
6+ "bufio"
67 "fmt"
78 "io/ioutil"
9+ "os"
810 "path/filepath"
911 "strconv"
1012 "strings"
@@ -16,8 +18,14 @@ import (
1618)
1719
1820const (
19- cgroupCpuacctStat = "cpuacct.stat"
21+ cgroupCpuacctStat = "cpuacct.stat"
22+ cgroupCpuacctUsageAll = "cpuacct.usage_all"
23+
2024 nanosecondsInSecond = 1000000000
25+
26+ userModeColumn = 1
27+ kernelModeColumn = 2
28+ cuacctUsageAllColumnsNumber = 3
2129)
2230
2331var clockTicks = uint64 (system .GetClockTicks ())
@@ -62,8 +70,15 @@ func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error {
6270 return err
6371 }
6472
73+ percpuUsageInKernelmode , percpuUsageInUsermode , err := getPercpuUsageInModes (path )
74+ if err != nil {
75+ return err
76+ }
77+
6578 stats .CpuStats .CpuUsage .TotalUsage = totalUsage
6679 stats .CpuStats .CpuUsage .PercpuUsage = percpuUsage
80+ stats .CpuStats .CpuUsage .PercpuUsageInKernelmode = percpuUsageInKernelmode
81+ stats .CpuStats .CpuUsage .PercpuUsageInUsermode = percpuUsageInUsermode
6782 stats .CpuStats .CpuUsage .UsageInUsermode = userModeUsage
6883 stats .CpuStats .CpuUsage .UsageInKernelmode = kernelModeUsage
6984 return nil
@@ -120,3 +135,42 @@ func getPercpuUsage(path string) ([]uint64, error) {
120135 }
121136 return percpuUsage , nil
122137}
138+
139+ func getPercpuUsageInModes (path string ) ([]uint64 , []uint64 , error ) {
140+ usageKernelMode := []uint64 {}
141+ usageUserMode := []uint64 {}
142+
143+ file , err := os .Open (filepath .Join (path , cgroupCpuacctUsageAll ))
144+ if err != nil {
145+ return nil , nil , err
146+ }
147+ defer file .Close ()
148+
149+ scanner := bufio .NewScanner (file )
150+ scanner .Scan () //skipping header line
151+
152+ for scanner .Scan () {
153+ lineFields := strings .SplitN (scanner .Text (), " " , cuacctUsageAllColumnsNumber )
154+ if len (lineFields ) != cuacctUsageAllColumnsNumber {
155+ continue
156+ }
157+
158+ usageInKernelMode , err := strconv .ParseUint (lineFields [kernelModeColumn ], 10 , 64 )
159+ if err != nil {
160+ return nil , nil , fmt .Errorf ("Unable to convert CPU usage in kernel mode to uint64: %s" , err )
161+ }
162+ usageKernelMode = append (usageKernelMode , usageInKernelMode )
163+
164+ usageInUserMode , err := strconv .ParseUint (lineFields [userModeColumn ], 10 , 64 )
165+ if err != nil {
166+ return nil , nil , fmt .Errorf ("Unable to convert CPU usage in user mode to uint64: %s" , err )
167+ }
168+ usageUserMode = append (usageUserMode , usageInUserMode )
169+ }
170+
171+ if err := scanner .Err (); err != nil {
172+ return nil , nil , fmt .Errorf ("Problem in reading %s line by line, %s" , cgroupCpuacctUsageAll , err )
173+ }
174+
175+ return usageKernelMode , usageUserMode , nil
176+ }
0 commit comments