diff --git a/README.rst b/README.rst index a858ff0..bd93152 100644 --- a/README.rst +++ b/README.rst @@ -60,6 +60,7 @@ The output is below. {"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip)} You can set an alternative location to /proc by setting the HOST_PROC environment variable. +You can set an alternative location to /sys by setting the HOST_SYS environment variable. Documentation ------------------------ diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index 1bec8a7..6a4e672 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -3,6 +3,8 @@ package cpu import ( + "path/filepath" + "fmt" "errors" "os/exec" "strconv" @@ -55,19 +57,41 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) { return ret, nil } +func sysCpuPath(cpu int32, relPath string) string { + root := common.GetEnv("HOST_SYS", "/sys") + return filepath.Join(root, fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath) +} + +func finishCPUInfo(c *CPUInfoStat) error { + if c.Mhz == 0 { + lines, err := common.ReadLines(sysCpuPath(c.CPU, "cpufreq/cpuinfo_max_freq")) + if err == nil { + value, err := strconv.ParseFloat(lines[0], 64) + if err != nil { + return err + } + c.Mhz = value + } + } + if len(c.CoreID) == 0 { + lines, err := common.ReadLines(sysCpuPath(c.CPU, "topology/core_id")) + if err == nil { + c.CoreID = lines[0] + } + } + return nil +} + func CPUInfo() ([]CPUInfoStat, error) { - filename := common.GetEnv("HOST_PROC", "/proc") + "cpuinfo" + filename := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), "cpuinfo") lines, _ := common.ReadLines(filename) var ret []CPUInfoStat - var c CPUInfoStat + c := CPUInfoStat{CPU: -1} for _, line := range lines { fields := strings.Split(line, ":") if len(fields) < 2 { - if c.VendorID != "" { - ret = append(ret, c) - } continue } key := strings.TrimSpace(fields[0]) @@ -75,6 +99,13 @@ func CPUInfo() ([]CPUInfoStat, error) { switch key { case "processor": + if c.CPU >= 0 { + err := finishCPUInfo(&c) + if err != nil { + return ret, err + } + ret = append(ret, c) + } c = CPUInfoStat{} t, err := strconv.ParseInt(value, 10, 64) if err != nil { @@ -117,9 +148,18 @@ func CPUInfo() ([]CPUInfoStat, error) { return ret, err } c.Cores = int32(t) - case "flags": - c.Flags = strings.Split(value, ",") + case "flags","Features": + c.Flags = strings.FieldsFunc(value, func(r rune) bool { + return r == ',' || r == ' ' + }) + } + } + if c.CPU >= 0 { + err := finishCPUInfo(&c) + if err != nil { + return ret, err } + ret = append(ret, c) } return ret, nil }