summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean E. Russell <ser@ser1.net>2020-02-19 13:05:52 -0600
committerSean E. Russell <ser@ser1.net>2020-02-19 13:05:52 -0600
commit463519cae235bb0276bb0a2aa1d951339b0a540c (patch)
tree8f963070138623d93eb33b166de707c05766ab22
parentf96a97c3d8f5b8cd87a6e2f1fd1d0a4032c429a7 (diff)
Fixes #50. Replace forked ps with builtin gopsutil which should save some CPU cyclesgopsutil_procs
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rw-r--r--widgets/proc.go32
-rw-r--r--widgets/proc_freebsd.go66
-rw-r--r--widgets/proc_linux.go45
-rw-r--r--widgets/proc_other.go57
-rw-r--r--widgets/proc_windows.go44
7 files changed, 34 insertions, 214 deletions
diff --git a/go.mod b/go.mod
index 6058002..8db3fab 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
github.com/go-ole/go-ole v1.2.1 // indirect
github.com/mattn/go-runewidth v0.0.4
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
- github.com/prometheus/client_golang v1.4.1
+ github.com/prometheus/client_golang v1.4.1 // indirect
github.com/shirou/gopsutil v2.18.11+incompatible
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
github.com/stretchr/testify v1.4.0
diff --git a/go.sum b/go.sum
index aaabcf8..7d42d4c 100644
--- a/go.sum
+++ b/go.sum
@@ -100,7 +100,6 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
github.com/shirou/gopsutil v2.18.11+incompatible h1:PMFTKnFTr/YTRW5rbLK4vWALV3a+IGXse5nvhSjztmg=
github.com/shirou/gopsutil v2.18.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY=
-github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -137,6 +136,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
diff --git a/widgets/proc.go b/widgets/proc.go
index 9fed067..6e29db7 100644
--- a/widgets/proc.go
+++ b/widgets/proc.go
@@ -12,6 +12,7 @@ import (
psCPU "github.com/shirou/gopsutil/cpu"
tui "github.com/gizak/termui/v3"
+ "github.com/shirou/gopsutil/process"
ui "github.com/xxxserxxx/gotop/termui"
"github.com/xxxserxxx/gotop/utils"
)
@@ -329,3 +330,34 @@ func (self SortProcsByMem) Swap(i, j int) {
func (self SortProcsByMem) Less(i, j int) bool {
return self[i].Mem < self[j].Mem
}
+
+func getProcs() ([]Proc, error) {
+ procs, err := process.Processes()
+ if err != nil {
+ return nil, err
+ }
+ rv := make([]Proc, len(procs))
+ for i, p := range procs {
+ cmdLine, err := p.Cmdline()
+ if err != nil {
+ return nil, err
+ }
+ cmd, err := p.Name()
+ if err != nil {
+ return nil, err
+ }
+ cpu, err := p.CPUPercent()
+ if err != nil {
+ return nil, err
+ }
+ mem, err := p.MemoryPercent()
+ rv[i] = Proc{
+ Pid: int(p.Pid),
+ CommandName: cmd,
+ FullCommand: cmdLine,
+ Cpu: cpu,
+ Mem: float64(mem),
+ }
+ }
+ return rv, nil
+}
diff --git a/widgets/proc_freebsd.go b/widgets/proc_freebsd.go
deleted file mode 100644
index ac3e73f..0000000
--- a/widgets/proc_freebsd.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package widgets
-
-import (
- "encoding/json"
- "fmt"
- "log"
- "os/exec"
- "strconv"
- "strings"
-
- "github.com/xxxserxxx/gotop/utils"
-)
-
-type processList struct {
- ProcessInformation struct {
- Process []struct {
- Pid string `json:"pid"`
- Comm string `json:"command"`
- Cpu string `json:"percent-cpu" `
- Mem string `json:"percent-memory" `
- Args string `json:"arguments" `
- } `json:"process"`
- } `json:"process-information"`
-}
-
-func getProcs() ([]Proc, error) {
- output, err := exec.Command("ps", "-axo pid,comm,%cpu,%mem,args", "--libxo", "json").Output()
- if err != nil {
- return nil, fmt.Errorf("failed to execute 'ps' command: %v", err)
- }
-
- list := processList{}
- err = json.Unmarshal(output, &list)
- if err != nil {
- return nil, fmt.Errorf("failed to unmarshal json. %s", err)
- }
- procs := []Proc{}
-
- for _, process := range list.ProcessInformation.Process {
- if process.Comm == "idle" {
- continue
- }
- pid, err := strconv.Atoi(strings.TrimSpace(process.Pid))
- if err != nil {
- log.Printf("failed to convert first field to int: %v. split: %v", err, process)
- }
- cpu, err := strconv.ParseFloat(utils.ConvertLocalizedString(process.Cpu), 32)
- if err != nil {
- log.Printf("failed to convert third field to float: %v. split: %v", err, process)
- }
- mem, err := strconv.ParseFloat(utils.ConvertLocalizedString(process.Mem), 32)
- if err != nil {
- log.Printf("failed to convert fourth field to float: %v. split: %v", err, process)
- }
- proc := Proc{
- Pid: pid,
- CommandName: process.Comm,
- Cpu: cpu,
- Mem: mem,
- FullCommand: process.Args,
- }
- procs = append(procs, proc)
- }
-
- return procs, nil
-}
diff --git a/widgets/proc_linux.go b/widgets/proc_linux.go
deleted file mode 100644
index 0045234..0000000
--- a/widgets/proc_linux.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package widgets
-
-import (
- "fmt"
- "log"
- "os/exec"
- "strconv"
- "strings"
-)
-
-func getProcs() ([]Proc, error) {
- output, err := exec.Command("ps", "-axo", "pid:10,comm:50,pcpu:5,pmem:5,args").Output()
- if err != nil {
- return nil, fmt.Errorf("failed to execute 'ps' command: %v", err)
- }
-
- // converts to []string, removing trailing newline and header
- linesOfProcStrings := strings.Split(strings.TrimSuffix(string(output), "\n"), "\n")[1:]
-
- procs := []Proc{}
- for _, line := range linesOfProcStrings {
- pid, err := strconv.Atoi(strings.TrimSpace(line[0:10]))
- if err != nil {
- log.Printf("failed to convert PID to int: %v. line: %v", err, line)
- }
- cpu, err := strconv.ParseFloat(strings.TrimSpace(line[63:68]), 64)
- if err != nil {
- log.Printf("failed to convert CPU usage to float: %v. line: %v", err, line)
- }
- mem, err := strconv.ParseFloat(strings.TrimSpace(line[69:74]), 64)
- if err != nil {
- log.Printf("failed to convert Mem usage to float: %v. line: %v", err, line)
- }
- proc := Proc{
- Pid: pid,
- CommandName: strings.TrimSpace(line[11:61]),
- FullCommand: line[74:],
- Cpu: cpu,
- Mem: mem,
- }
- procs = append(procs, proc)
- }
-
- return procs, nil
-}
diff --git a/widgets/proc_other.go b/widgets/proc_other.go
deleted file mode 100644
index 09aac28..0000000
--- a/widgets/proc_other.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// +build darwin openbsd
-
-package widgets
-
-import (
- "fmt"
- "log"
- "os/exec"
- "strconv"
- "strings"
-
- "github.com/xxxserxxx/gotop/utils"
-)
-
-const (
- // Define column widths for ps output used in Procs()
- five = "12345"
- ten = five + five
- fifty = ten + ten + ten + ten + ten
-)
-
-func getProcs() ([]Proc, error) {
- keywords := fmt.Sprintf("pid=%s,comm=%s,pcpu=%s,pmem=%s,args", ten, fifty, five, five)
- output, err := exec.Command("ps", "-caxo", keywords).Output()
- if err != nil {
- return nil, fmt.Errorf("failed to execute 'ps' command: %v", err)
- }
-
- // converts to []string and removes the header
- linesOfProcStrings := strings.Split(strings.TrimSpace(string(output)), "\n")[1:]
-
- procs := []Proc{}
- for _, line := range linesOfProcStrings {
- pid, err := strconv.Atoi(strings.TrimSpace(line[0:10]))
- if err != nil {
- log.Printf("failed to convert first field to int: %v. split: %v", err, line)
- }
- cpu, err := strconv.ParseFloat(utils.ConvertLocalizedString(strings.TrimSpace(line[63:68])), 64)
- if err != nil {
- log.Printf("failed to convert third field to float: %v. split: %v", err, line)
- }
- mem, err := strconv.ParseFloat(utils.ConvertLocalizedString(strings.TrimSpace(line[69:74])), 64)
- if err != nil {
- log.Printf("failed to convert fourth field to float: %v. split: %v", err, line)
- }
- proc := Proc{
- Pid: pid,
- CommandName: strings.TrimSpace(line[11:61]),
- Cpu: cpu,
- Mem: mem,
- FullCommand: line[74:],
- }
- procs = append(procs, proc)
- }
-
- return procs, nil
-}
diff --git a/widgets/proc_windows.go b/widgets/proc_windows.go
deleted file mode 100644
index adc49e9..0000000
--- a/widgets/proc_windows.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package widgets
-
-import (
- "fmt"
- "log"
-
- psProc "github.com/shirou/gopsutil/process"
-)
-
-func getProcs() ([]Proc, error) {
- psProcs, err := psProc.Processes()
- if err != nil {
- return nil, fmt.Errorf("failed to get processes from gopsutil: %v", err)
- }
-
- procs := make([]Proc, len(psProcs))
- for i, psProc := range psProcs {
- pid := psProc.Pid
- command, err := psProc.Name()
- if err != nil {
- log.Printf("failed to get process command from gopsutil: %v. psProc: %v. i: %v. pid: %v", err, psProc, i, pid)
- }
- cpu, err := psProc.CPUPercent()
- if err != nil {
- log.Printf("failed to get process cpu usage from gopsutil: %v. psProc: %v. i: %v. pid: %v", err, psProc, i, pid)
- }
- mem, err := psProc.MemoryPercent()
- if err != nil {
- log.Printf("failed to get process memeory usage from gopsutil: %v. psProc: %v. i: %v. pid: %v", err, psProc, i, pid)
- }
-
- procs[i] = Proc{
- Pid: int(pid),
- CommandName: command,
- Cpu: cpu,
- Mem: float64(mem),
- // getting command args using gopsutil's Cmdline and CmdlineSlice wasn't
- // working the last time I tried it, so we're just reusing 'command'
- FullCommand: command,
- }
- }
-
- return procs, nil
-}