process: implement cpu_percent on linux.
This commit is contained in:
parent
e71113cffd
commit
2093d43c2a
|
@ -2,6 +2,10 @@ package process
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
cpu "github.com/shirou/gopsutil/cpu"
|
||||
)
|
||||
|
||||
type Process struct {
|
||||
|
@ -13,6 +17,9 @@ type Process struct {
|
|||
gids []int32
|
||||
numThreads int32
|
||||
memInfo *MemoryInfoStat
|
||||
|
||||
lastCPUTimes *cpu.CPUTimesStat
|
||||
lastCPUTime time.Time
|
||||
}
|
||||
|
||||
type OpenFilesStat struct {
|
||||
|
@ -88,3 +95,48 @@ func PidExists(pid int32) (bool, error) {
|
|||
|
||||
return false, err
|
||||
}
|
||||
|
||||
// If interval is 0, return difference from last call(non-blocking).
|
||||
// If interval > 0, wait interval sec and return diffrence between start and end.
|
||||
func (p *Process) CPUPercent(interval time.Duration) (float64, error) {
|
||||
calculate := func(t1, t2 *cpu.CPUTimesStat, delta float64) float64 {
|
||||
if delta == 0 {
|
||||
return 0
|
||||
}
|
||||
numcpu := runtime.NumCPU()
|
||||
delta_proc := (t2.User - t1.User) + (t2.System - t1.System)
|
||||
overall_percent := ((delta_proc / delta) * 100) * float64(numcpu)
|
||||
return overall_percent
|
||||
}
|
||||
|
||||
cpuTimes, err := p.CPUTimes()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if interval > 0 {
|
||||
p.lastCPUTimes = cpuTimes
|
||||
p.lastCPUTime = time.Now()
|
||||
time.Sleep(interval)
|
||||
cpuTimes, err = p.CPUTimes()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
if p.lastCPUTimes == nil {
|
||||
// invoked first time
|
||||
p.lastCPUTimes, err = p.CPUTimes()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
p.lastCPUTime = time.Now()
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
|
||||
delta := (time.Now().Sub(p.lastCPUTime).Seconds()) * 1000
|
||||
ret := calculate(p.lastCPUTimes, cpuTimes, float64(delta))
|
||||
p.lastCPUTimes = cpuTimes
|
||||
p.lastCPUTime = time.Now()
|
||||
return ret, nil
|
||||
}
|
||||
|
|
|
@ -148,9 +148,6 @@ func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
|
|||
}
|
||||
return cpuTimes, nil
|
||||
}
|
||||
func (p *Process) CPUPercent() (int32, error) {
|
||||
return 0, common.NotImplementedError
|
||||
}
|
||||
func (p *Process) CPUAffinity() ([]int32, error) {
|
||||
return nil, common.NotImplementedError
|
||||
}
|
||||
|
@ -545,6 +542,7 @@ func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32
|
|||
if err != nil {
|
||||
return "", 0, nil, 0, 0, err
|
||||
}
|
||||
|
||||
stime, err := strconv.ParseFloat(fields[14], 64)
|
||||
if err != nil {
|
||||
return "", 0, nil, 0, 0, err
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func testGetProcess() Process {
|
||||
|
@ -126,3 +127,38 @@ func Test_Process_Nice(t *testing.T) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Process_CpuPercent(t *testing.T) {
|
||||
p := testGetProcess()
|
||||
percent, err := p.CPUPercent(0)
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
duration := time.Duration(1000) * time.Microsecond
|
||||
time.Sleep(duration)
|
||||
percent, err = p.CPUPercent(0)
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
|
||||
numcpu := runtime.NumCPU()
|
||||
if percent < 0.0 || percent > 100.0*float64(numcpu) {
|
||||
t.Fatalf("CPUPercent value is invalid: %f", percent)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Process_CpuPercentLoop(t *testing.T) {
|
||||
p := testGetProcess()
|
||||
numcpu := runtime.NumCPU()
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
duration := time.Duration(100) * time.Microsecond
|
||||
percent, err := p.CPUPercent(duration)
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
if percent < 0.0 || percent > 100.0*float64(numcpu) {
|
||||
t.Fatalf("CPUPercent value is invalid: %f", percent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue