package process import ( "encoding/json" "runtime" "time" "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/mem" ) var invoke common.Invoker func init() { invoke = common.Invoke{} } type Process struct { Pid int32 `json:"pid"` name string status string parent int32 numCtxSwitches *NumCtxSwitchesStat uids []int32 gids []int32 numThreads int32 memInfo *MemoryInfoStat lastCPUTimes *cpu.TimesStat lastCPUTime time.Time } type OpenFilesStat struct { Path string `json:"path"` Fd uint64 `json:"fd"` } type MemoryInfoStat struct { RSS uint64 `json:"rss"` // bytes VMS uint64 `json:"vms"` // bytes Swap uint64 `json:"swap"` // bytes } type RlimitStat struct { Resource int32 `json:"resource"` Soft int32 `json:"soft"` Hard int32 `json:"hard"` } type IOCountersStat struct { ReadCount uint64 `json:"readCount"` WriteCount uint64 `json:"writeCount"` ReadBytes uint64 `json:"readBytes"` WriteBytes uint64 `json:"writeBytes"` } type NumCtxSwitchesStat struct { Voluntary int64 `json:"voluntary"` Involuntary int64 `json:"involuntary"` } func (p Process) String() string { s, _ := json.Marshal(p) return string(s) } func (o OpenFilesStat) String() string { s, _ := json.Marshal(o) return string(s) } func (m MemoryInfoStat) String() string { s, _ := json.Marshal(m) return string(s) } func (r RlimitStat) String() string { s, _ := json.Marshal(r) return string(s) } func (i IOCountersStat) String() string { s, _ := json.Marshal(i) return string(s) } func (p NumCtxSwitchesStat) String() string { s, _ := json.Marshal(p) return string(s) } func PidExists(pid int32) (bool, error) { pids, err := Pids() if err != nil { return false, err } for _, i := range pids { if i == pid { return true, err } } 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) Percent(interval time.Duration) (float64, error) { cpuTimes, err := p.Times() if err != nil { return 0, err } now := time.Now() if interval > 0 { p.lastCPUTimes = cpuTimes p.lastCPUTime = now time.Sleep(interval) cpuTimes, err = p.Times() now = time.Now() if err != nil { return 0, err } } else { if p.lastCPUTimes == nil { // invoked first time p.lastCPUTimes = cpuTimes p.lastCPUTime = now return 0, nil } } numcpu := runtime.NumCPU() delta := (now.Sub(p.lastCPUTime).Seconds()) * float64(numcpu) ret := calculatePercent(p.lastCPUTimes, cpuTimes, delta, numcpu) p.lastCPUTimes = cpuTimes p.lastCPUTime = now return ret, nil } func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64 { if delta == 0 { return 0 } delta_proc := t2.Total() - t1.Total() overall_percent := ((delta_proc / delta) * 100) * float64(numcpu) return overall_percent } // MemoryPercent returns how many percent of the total RAM this process uses func (p *Process) MemoryPercent() (float32, error) { machineMemory, err := mem.VirtualMemory() if err != nil { return 0, err } total := machineMemory.Total processMemory, err := p.MemoryInfo() if err != nil { return 0, err } used := processMemory.RSS return (100 * float32(used) / float32(total)), nil }