mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
Add reading of information from cpuacct.usage_all
Remove logrus logs from tests Signed-off-by: Katarzyna Kujawa <katarzyna.kujawa@intel.com>
This commit is contained in:
@@ -125,6 +125,8 @@ func convertLibcontainerStats(ls *libcontainer.Stats) *types.Stats {
|
|||||||
s.CPU.Usage.User = cg.CpuStats.CpuUsage.UsageInUsermode
|
s.CPU.Usage.User = cg.CpuStats.CpuUsage.UsageInUsermode
|
||||||
s.CPU.Usage.Total = cg.CpuStats.CpuUsage.TotalUsage
|
s.CPU.Usage.Total = cg.CpuStats.CpuUsage.TotalUsage
|
||||||
s.CPU.Usage.Percpu = cg.CpuStats.CpuUsage.PercpuUsage
|
s.CPU.Usage.Percpu = cg.CpuStats.CpuUsage.PercpuUsage
|
||||||
|
s.CPU.Usage.PercpuKernel = cg.CpuStats.CpuUsage.PercpuUsageInKernelmode
|
||||||
|
s.CPU.Usage.PercpuUser = cg.CpuStats.CpuUsage.PercpuUsageInUsermode
|
||||||
s.CPU.Throttling.Periods = cg.CpuStats.ThrottlingData.Periods
|
s.CPU.Throttling.Periods = cg.CpuStats.ThrottlingData.Periods
|
||||||
s.CPU.Throttling.ThrottledPeriods = cg.CpuStats.ThrottlingData.ThrottledPeriods
|
s.CPU.Throttling.ThrottledPeriods = cg.CpuStats.ThrottlingData.ThrottledPeriods
|
||||||
s.CPU.Throttling.ThrottledTime = cg.CpuStats.ThrottlingData.ThrottledTime
|
s.CPU.Throttling.ThrottledTime = cg.CpuStats.ThrottlingData.ThrottledTime
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
package fs
|
package fs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -15,9 +17,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cgroupCpuacctStat = "cpuacct.stat"
|
cgroupCpuacctStat = "cpuacct.stat"
|
||||||
|
cgroupCpuacctUsageAll = "cpuacct.usage_all"
|
||||||
|
|
||||||
nanosecondsInSecond = 1000000000
|
nanosecondsInSecond = 1000000000
|
||||||
|
|
||||||
|
userModeColumn = 1
|
||||||
|
kernelModeColumn = 2
|
||||||
|
cuacctUsageAllColumnsNumber = 3
|
||||||
|
|
||||||
// The value comes from `C.sysconf(C._SC_CLK_TCK)`, and
|
// The value comes from `C.sysconf(C._SC_CLK_TCK)`, and
|
||||||
// on Linux it's a constant which is safe to be hard coded,
|
// on Linux it's a constant which is safe to be hard coded,
|
||||||
// so we can avoid using cgo here. For details, see:
|
// so we can avoid using cgo here. For details, see:
|
||||||
@@ -65,8 +73,15 @@ func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
percpuUsageInKernelmode, percpuUsageInUsermode, err := getPercpuUsageInModes(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
stats.CpuStats.CpuUsage.TotalUsage = totalUsage
|
stats.CpuStats.CpuUsage.TotalUsage = totalUsage
|
||||||
stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage
|
stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage
|
||||||
|
stats.CpuStats.CpuUsage.PercpuUsageInKernelmode = percpuUsageInKernelmode
|
||||||
|
stats.CpuStats.CpuUsage.PercpuUsageInUsermode = percpuUsageInUsermode
|
||||||
stats.CpuStats.CpuUsage.UsageInUsermode = userModeUsage
|
stats.CpuStats.CpuUsage.UsageInUsermode = userModeUsage
|
||||||
stats.CpuStats.CpuUsage.UsageInKernelmode = kernelModeUsage
|
stats.CpuStats.CpuUsage.UsageInKernelmode = kernelModeUsage
|
||||||
return nil
|
return nil
|
||||||
@@ -123,3 +138,42 @@ func getPercpuUsage(path string) ([]uint64, error) {
|
|||||||
}
|
}
|
||||||
return percpuUsage, nil
|
return percpuUsage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) {
|
||||||
|
usageKernelMode := []uint64{}
|
||||||
|
usageUserMode := []uint64{}
|
||||||
|
|
||||||
|
file, err := os.Open(filepath.Join(path, cgroupCpuacctUsageAll))
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
scanner.Scan() //skipping header line
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
lineFields := strings.SplitN(scanner.Text(), " ", cuacctUsageAllColumnsNumber+1)
|
||||||
|
if len(lineFields) != cuacctUsageAllColumnsNumber {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
usageInKernelMode, err := strconv.ParseUint(lineFields[kernelModeColumn], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("Unable to convert CPU usage in kernel mode to uint64: %s", err)
|
||||||
|
}
|
||||||
|
usageKernelMode = append(usageKernelMode, usageInKernelMode)
|
||||||
|
|
||||||
|
usageInUserMode, err := strconv.ParseUint(lineFields[userModeColumn], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("Unable to convert CPU usage in user mode to uint64: %s", err)
|
||||||
|
}
|
||||||
|
usageUserMode = append(usageUserMode, usageInUserMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("Problem in reading %s line by line, %s", cgroupCpuacctUsageAll, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return usageKernelMode, usageUserMode, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
|
package fs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cpuAcctUsageContents = "12262454190222160"
|
||||||
|
cpuAcctUsagePerCPUContents = "1564936537989058 1583937096487821 1604195415465681 1596445226820187 1481069084155629 1478735613864327 1477610593414743 1476362015778086"
|
||||||
|
cpuAcctStatContents = "user 452278264\nsystem 291429664"
|
||||||
|
cpuAcctUsageAll = `cpu user system
|
||||||
|
0 962250696038415 637727786389114
|
||||||
|
1 981956408513304 638197595421064
|
||||||
|
2 1002658817529022 638956774598358
|
||||||
|
3 994937703492523 637985531181620
|
||||||
|
4 874843781648690 638837766495476
|
||||||
|
5 872544369885276 638763309884944
|
||||||
|
6 870104915696359 640081778921247
|
||||||
|
7 870202363887496 638716766259495
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCpuacctStats(t *testing.T) {
|
||||||
|
helper := NewCgroupTestUtil("cpuacct.", t)
|
||||||
|
defer helper.cleanup()
|
||||||
|
helper.writeFileContents(map[string]string{
|
||||||
|
"cpuacct.usage": cpuAcctUsageContents,
|
||||||
|
"cpuacct.usage_percpu": cpuAcctUsagePerCPUContents,
|
||||||
|
"cpuacct.stat": cpuAcctStatContents,
|
||||||
|
"cpuacct.usage_all": cpuAcctUsageAll,
|
||||||
|
})
|
||||||
|
|
||||||
|
cpuacct := &CpuacctGroup{}
|
||||||
|
actualStats := *cgroups.NewStats()
|
||||||
|
err := cpuacct.GetStats(helper.CgroupPath, &actualStats)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedStats := cgroups.CpuUsage{
|
||||||
|
TotalUsage: uint64(12262454190222160),
|
||||||
|
PercpuUsage: []uint64{1564936537989058, 1583937096487821, 1604195415465681, 1596445226820187,
|
||||||
|
1481069084155629, 1478735613864327, 1477610593414743, 1476362015778086},
|
||||||
|
PercpuUsageInKernelmode: []uint64{637727786389114, 638197595421064, 638956774598358, 637985531181620,
|
||||||
|
638837766495476, 638763309884944, 640081778921247, 638716766259495},
|
||||||
|
PercpuUsageInUsermode: []uint64{962250696038415, 981956408513304, 1002658817529022, 994937703492523,
|
||||||
|
874843781648690, 872544369885276, 870104915696359, 870202363887496},
|
||||||
|
UsageInKernelmode: (uint64(291429664) * nanosecondsInSecond) / clockTicks,
|
||||||
|
UsageInUsermode: (uint64(452278264) * nanosecondsInSecond) / clockTicks,
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(expectedStats, actualStats.CpuStats.CpuUsage) {
|
||||||
|
t.Errorf("Expected CPU usage %#v but found %#v\n",
|
||||||
|
expectedStats, actualStats.CpuStats.CpuUsage)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,12 @@ type CpuUsage struct {
|
|||||||
// Total CPU time consumed per core.
|
// Total CPU time consumed per core.
|
||||||
// Units: nanoseconds.
|
// Units: nanoseconds.
|
||||||
PercpuUsage []uint64 `json:"percpu_usage,omitempty"`
|
PercpuUsage []uint64 `json:"percpu_usage,omitempty"`
|
||||||
|
// CPU time consumed per core in kernel mode
|
||||||
|
// Units: nanoseconds.
|
||||||
|
PercpuUsageInKernelmode []uint64 `json:"percpu_usage_in_kernelmode"`
|
||||||
|
// CPU time consumed per core in user mode
|
||||||
|
// Units: nanoseconds.
|
||||||
|
PercpuUsageInUsermode []uint64 `json:"percpu_usage_in_usermode"`
|
||||||
// Time spent by tasks of the cgroup in kernel mode.
|
// Time spent by tasks of the cgroup in kernel mode.
|
||||||
// Units: nanoseconds.
|
// Units: nanoseconds.
|
||||||
UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
|
UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
|
||||||
|
|||||||
+6
-4
@@ -55,10 +55,12 @@ type Throttling struct {
|
|||||||
|
|
||||||
type CpuUsage struct {
|
type CpuUsage struct {
|
||||||
// Units: nanoseconds.
|
// Units: nanoseconds.
|
||||||
Total uint64 `json:"total,omitempty"`
|
Total uint64 `json:"total,omitempty"`
|
||||||
Percpu []uint64 `json:"percpu,omitempty"`
|
Percpu []uint64 `json:"percpu,omitempty"`
|
||||||
Kernel uint64 `json:"kernel"`
|
PercpuKernel []uint64 `json:"percpu_kernel,omitempty"`
|
||||||
User uint64 `json:"user"`
|
PercpuUser []uint64 `json:"percpu_user,omitempty"`
|
||||||
|
Kernel uint64 `json:"kernel"`
|
||||||
|
User uint64 `json:"user"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Cpu struct {
|
type Cpu struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user