1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-04-26 13:48:59 +08:00

cpu: use wmic to get CPU usage on Windows.

This commit is contained in:
WAKAYAMA Shirou 2015-03-11 23:00:06 +09:00
parent 1851e63d38
commit ead8393137
4 changed files with 119 additions and 55 deletions

View File

@ -5,7 +5,6 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"time"
) )
type CPUTimesStat struct { type CPUTimesStat struct {
@ -38,62 +37,11 @@ type CPUInfoStat struct {
Flags []string `json:"flags"` Flags []string `json:"flags"`
} }
func CPUCounts(logical bool) (int, error) {
return runtime.NumCPU(), nil
}
var lastCPUTimes []CPUTimesStat var lastCPUTimes []CPUTimesStat
var lastPerCPUTimes []CPUTimesStat var lastPerCPUTimes []CPUTimesStat
func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) { func CPUCounts(logical bool) (int, error) {
getAllBusy := func(t CPUTimesStat) (float64, float64) { return runtime.NumCPU(), nil
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen
return busy + t.Idle, busy
}
calculate := func(t1, t2 CPUTimesStat) float64 {
t1All, t1Busy := getAllBusy(t1)
t2All, t2Busy := getAllBusy(t2)
if t2Busy <= t1Busy {
return 0
}
if t2All <= t1All {
return 1
}
return (t2Busy - t1Busy) / (t2All - t1All) * 100
}
cpuTimes, err := CPUTimes(percpu)
if err != nil {
return nil, err
}
if interval > 0 {
if !percpu {
lastCPUTimes = cpuTimes
} else {
lastPerCPUTimes = cpuTimes
}
time.Sleep(interval)
cpuTimes, err = CPUTimes(percpu)
if err != nil {
return nil, err
}
}
ret := make([]float64, len(cpuTimes))
if !percpu {
ret[0] = calculate(lastCPUTimes[0], cpuTimes[0])
lastCPUTimes = cpuTimes
} else {
for i, t := range cpuTimes {
ret[i] = calculate(lastPerCPUTimes[i], t)
}
lastPerCPUTimes = cpuTimes
}
return ret, nil
} }
func (c CPUTimesStat) String() string { func (c CPUTimesStat) String() string {

View File

@ -63,7 +63,10 @@ func TestCpuInfo(t *testing.T) {
func testCPUPercent(t *testing.T, percpu bool) { func testCPUPercent(t *testing.T, percpu bool) {
numcpu := runtime.NumCPU() numcpu := runtime.NumCPU()
testCount := 3
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
testCount = 100
v, err := CPUPercent(time.Millisecond, percpu) v, err := CPUPercent(time.Millisecond, percpu)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
@ -72,7 +75,7 @@ func testCPUPercent(t *testing.T, percpu bool) {
t.Fatalf("wrong number of entries from CPUPercent: %v", v) t.Fatalf("wrong number of entries from CPUPercent: %v", v)
} }
} }
for i := 0; i < 100; i++ { for i := 0; i < testCount; i++ {
duration := time.Duration(10) * time.Microsecond duration := time.Duration(10) * time.Microsecond
v, err := CPUPercent(duration, percpu) v, err := CPUPercent(duration, percpu)
if err != nil { if err != nil {

90
cpu/cpu_unix.go Normal file
View File

@ -0,0 +1,90 @@
// +build linux,freebsd,darwin
package cpu
import (
"encoding/json"
"strconv"
"strings"
"time"
)
func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) {
getAllBusy := func(t CPUTimesStat) (float64, float64) {
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen
return busy + t.Idle, busy
}
calculate := func(t1, t2 CPUTimesStat) float64 {
t1All, t1Busy := getAllBusy(t1)
t2All, t2Busy := getAllBusy(t2)
if t2Busy <= t1Busy {
return 0
}
if t2All <= t1All {
return 1
}
return (t2Busy - t1Busy) / (t2All - t1All) * 100
}
cpuTimes, err := CPUTimes(percpu)
if err != nil {
return nil, err
}
if interval > 0 {
if !percpu {
lastCPUTimes = cpuTimes
} else {
lastPerCPUTimes = cpuTimes
}
time.Sleep(interval)
cpuTimes, err = CPUTimes(percpu)
if err != nil {
return nil, err
}
}
ret := make([]float64, len(cpuTimes))
if !percpu {
ret[0] = calculate(lastCPUTimes[0], cpuTimes[0])
lastCPUTimes = cpuTimes
} else {
for i, t := range cpuTimes {
ret[i] = calculate(lastPerCPUTimes[i], t)
}
lastPerCPUTimes = cpuTimes
}
return ret, nil
}
func (c CPUTimesStat) String() string {
v := []string{
`"cpu":"` + c.CPU + `"`,
`"user":` + strconv.FormatFloat(c.User, 'f', 1, 64),
`"system":` + strconv.FormatFloat(c.System, 'f', 1, 64),
`"idle":` + strconv.FormatFloat(c.Idle, 'f', 1, 64),
`"nice":` + strconv.FormatFloat(c.Nice, 'f', 1, 64),
`"iowait":` + strconv.FormatFloat(c.Iowait, 'f', 1, 64),
`"irq":` + strconv.FormatFloat(c.Irq, 'f', 1, 64),
`"softirq":` + strconv.FormatFloat(c.Softirq, 'f', 1, 64),
`"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64),
`"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64),
`"guest_nice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64),
`"stolen":` + strconv.FormatFloat(c.Stolen, 'f', 1, 64),
}
return `{` + strings.Join(v, ",") + `}`
}
func (c CPUInfoStat) String() string {
s, _ := json.Marshal(c)
return string(s)
}
func init() {
lastCPUTimes, _ = CPUTimes(false)
lastPerCPUTimes, _ = CPUTimes(true)
}

View File

@ -6,6 +6,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
"time"
"unsafe" "unsafe"
common "github.com/shirou/gopsutil/common" common "github.com/shirou/gopsutil/common"
@ -79,3 +80,25 @@ func CPUInfo() ([]CPUInfoStat, error) {
} }
return ret, nil return ret, nil
} }
func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) {
ret := []float64{}
lines, err := common.GetWmic("cpu", "loadpercentage")
if err != nil {
return ret, err
}
for _, l := range lines {
t := strings.Split(l, ",")
if len(t) < 2 {
continue
}
p, err := strconv.Atoi(t[1])
if err != nil {
p = 0
}
ret = append(ret, float64(p)/100.0)
}
return ret, nil
}