| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package cgroup
- import (
- "fmt"
- "io/ioutil"
- "path"
- "strconv"
- "strings"
- )
- type CPUStat struct {
- UsageSeconds float64
- ThrottledTimeSeconds float64
- LimitCores float64
- }
- func (cg Cgroup) CpuStat() (*CPUStat, error) {
- if cg.Version == V1 {
- return cg.cpuStatV1()
- }
- return cg.cpuStatV2()
- }
- func (cg Cgroup) cpuStatV1() (*CPUStat, error) {
- throttling, err := readVariablesFromFile(path.Join(cgRoot, "cpu", cg.subsystems["cpu"], "cpu.stat"))
- if err != nil {
- return nil, err
- }
- usageNs, err := readIntFromFile(path.Join(cgRoot, "cpuacct", cg.subsystems["cpuacct"], "cpuacct.usage"))
- if err != nil {
- return nil, err
- }
- periodUs, err := readIntFromFile(path.Join(cgRoot, "cpu", cg.subsystems["cpu"], "cpu.cfs_period_us"))
- if err != nil {
- return nil, err
- }
- quotaUs, err := readIntFromFile(path.Join(cgRoot, "cpu", cg.subsystems["cpu"], "cpu.cfs_quota_us"))
- if err != nil {
- return nil, err
- }
- res := &CPUStat{
- UsageSeconds: float64(usageNs) / 1e9,
- ThrottledTimeSeconds: float64(throttling["throttled_time"]) / 1e9,
- }
- if quotaUs > 0 {
- res.LimitCores = float64(quotaUs) / float64(periodUs)
- }
- return res, nil
- }
- func (cg Cgroup) cpuStatV2() (*CPUStat, error) {
- vars, err := readVariablesFromFile(path.Join(cgRoot, cg.subsystems[""], "cpu.stat"))
- if err != nil {
- return nil, err
- }
- res := &CPUStat{
- UsageSeconds: float64(vars["usage_usec"]) / 1e6,
- ThrottledTimeSeconds: float64(vars["throttled_usec"]) / 1e6,
- }
- payload, err := ioutil.ReadFile(path.Join(cgRoot, cg.subsystems[""], "cpu.max"))
- if err != nil {
- return nil, err
- }
- data := strings.TrimSpace(string(payload))
- parts := strings.Fields(data)
- if len(parts) != 2 {
- return nil, fmt.Errorf("invalid cpu.max payload: %s", data)
- }
- if parts[0] == "max" { //no limit
- return res, nil
- }
- quotaUs, err := strconv.ParseUint(parts[0], 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid quota value in cpu.max: %s", parts[0])
- }
- periodUs, err := strconv.ParseUint(parts[1], 10, 64)
- if err != nil {
- return nil, fmt.Errorf("invalid period value in cpu.max: %s", parts[1])
- }
- if periodUs > 0 {
- res.LimitCores = float64(quotaUs) / float64(periodUs)
- }
- return res, nil
- }
|