Go vet/lint cleanups
This commit is contained in:
parent
1e78e6faa0
commit
285d4d0297
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/xxxserxxx/gotop/v4/devices"
|
||||
"github.com/xxxserxxx/gotop/v4/layout"
|
||||
"github.com/xxxserxxx/gotop/v4/logging"
|
||||
"github.com/xxxserxxx/gotop/v4/widgets"
|
||||
w "github.com/xxxserxxx/gotop/v4/widgets"
|
||||
)
|
||||
|
||||
|
@ -38,7 +39,9 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
Version = "0.0.0"
|
||||
// Version of the program; set during build from git tags
|
||||
Version = "0.0.0"
|
||||
// BuildDate when the program was compiled; set during build
|
||||
BuildDate = "Hadean"
|
||||
conf gotop.Config
|
||||
help *w.HelpMenu
|
||||
|
@ -104,9 +107,9 @@ func parseArgs(conf *gotop.Config) error {
|
|||
if *list != "" {
|
||||
switch *list {
|
||||
case "layouts":
|
||||
fmt.Println(LAYOUTS)
|
||||
fmt.Println(_layouts)
|
||||
case "colorschemes":
|
||||
fmt.Println(COLORSCHEMES)
|
||||
fmt.Println(_colorschemes)
|
||||
case "paths":
|
||||
fmt.Println("Loadable colorschemes & layouts, and the config file, are searched for, in order:")
|
||||
paths := make([]string, 0)
|
||||
|
@ -118,7 +121,7 @@ func parseArgs(conf *gotop.Config) error {
|
|||
case "devices":
|
||||
listDevices()
|
||||
case "keys":
|
||||
fmt.Println(KEYS)
|
||||
fmt.Println(widgets.KEYBINDS)
|
||||
default:
|
||||
fmt.Printf("Unknown option \"%s\"; try layouts, colorschemes, keys, paths, or devices\n", *list)
|
||||
os.Exit(1)
|
||||
|
@ -391,7 +394,7 @@ func run() int {
|
|||
}
|
||||
return 1
|
||||
}
|
||||
if err := ui.Init(); err != nil {
|
||||
if err = ui.Init(); err != nil {
|
||||
stderrLogger.Print(err)
|
||||
return 1
|
||||
}
|
||||
|
@ -481,40 +484,12 @@ func listDevices() {
|
|||
}
|
||||
}
|
||||
|
||||
const KEYS = `Quit: q or <C-c>
|
||||
Process navigation:
|
||||
k and <Up>: up
|
||||
j and <Down>: down
|
||||
<C-u>: half page up
|
||||
<C-d>: half page down
|
||||
<C-b>: full page up
|
||||
<C-f>: full page down
|
||||
gg and <Home>: jump to top
|
||||
G and <End>: jump to bottom
|
||||
Process actions:
|
||||
<Tab>: toggle process grouping
|
||||
dd: kill selected process or group of processes with SIGTERM
|
||||
d3: kill selected process or group of processes with SIGQUIT
|
||||
d9: kill selected process or group of processes with SIGKILL
|
||||
Process sorting
|
||||
c: CPU
|
||||
m: Mem
|
||||
p: PID
|
||||
Process filtering:
|
||||
/: start editing filter
|
||||
(while editing):
|
||||
<Enter> accept filter
|
||||
<C-c> and <Escape>: clear filter
|
||||
CPU and Mem graph scaling:
|
||||
h: scale in
|
||||
l: scale out
|
||||
?: toggles keybind help menu`
|
||||
const LAYOUTS = `Built-in layouts:
|
||||
const _layouts = `Built-in layouts:
|
||||
default
|
||||
minimal
|
||||
battery
|
||||
kitchensink`
|
||||
const COLORSCHEMES = `Built-in colorschemes:
|
||||
const _colorschemes = `Built-in colorschemes:
|
||||
default
|
||||
default-dark (for white background)
|
||||
solarized
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package colorschemes
|
||||
|
||||
import (
|
||||
"github.com/shibukawa/configdir"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
@ -8,8 +10,10 @@ import (
|
|||
func TestColorRegistry(t *testing.T) {
|
||||
colors := []string{"default", "default-dark", "solarized", "solarized16-dark", "solarized16-light", "monokai", "vice"}
|
||||
zeroCS := Colorscheme{}
|
||||
cd := configdir.New("", "gotop")
|
||||
cd.LocalPath, _ = filepath.Abs(".")
|
||||
for _, cn := range colors {
|
||||
c, e := FromName("", cn)
|
||||
c, e := FromName(cd, cn)
|
||||
if e != nil {
|
||||
t.Errorf("unexpected error fetching built-in color %s: %s", cn, e)
|
||||
}
|
||||
|
|
10
config.go
10
config.go
|
@ -48,7 +48,7 @@ func NewConfig() Config {
|
|||
PercpuLoad: true,
|
||||
TempScale: widgets.Celsius,
|
||||
Statusbar: false,
|
||||
NetInterface: widgets.NET_INTERFACE_ALL,
|
||||
NetInterface: widgets.NetInterfaceAll,
|
||||
MaxLogSize: 5000000,
|
||||
Layout: "default",
|
||||
ExtensionVars: make(map[string]string),
|
||||
|
@ -169,16 +169,16 @@ func load(in io.Reader, conf *Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) Write() (string, error) {
|
||||
func (conf *Config) Write() (string, error) {
|
||||
cfn := "gotop.conf"
|
||||
ds := c.ConfigDir.QueryFolders(configdir.Global)
|
||||
ds := conf.ConfigDir.QueryFolders(configdir.Global)
|
||||
if len(ds) == 0 {
|
||||
ds = c.ConfigDir.QueryFolders(configdir.Local)
|
||||
ds = conf.ConfigDir.QueryFolders(configdir.Local)
|
||||
if len(ds) == 0 {
|
||||
return "", fmt.Errorf("error locating config folders")
|
||||
}
|
||||
}
|
||||
marshalled := marshal(c)
|
||||
marshalled := marshal(conf)
|
||||
err := ds[0].WriteFile(cfn, marshalled)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
@ -78,7 +78,6 @@ func RegisterDeviceList(typ string, all func() []string, def func() []string) {
|
|||
func Devices(domain string, all bool) []string {
|
||||
if all {
|
||||
return _devs[domain]
|
||||
} else {
|
||||
return _defaults[domain]
|
||||
}
|
||||
return _defaults[domain]
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// Copyright 2020 The gotop Authors Licensed under terms of the LICENSE file in this repository.
|
||||
package layout
|
||||
|
||||
import (
|
||||
|
@ -165,7 +164,7 @@ func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
|
|||
dw := widgets.NewDiskWidget()
|
||||
w = dw
|
||||
case "cpu":
|
||||
cpu := widgets.NewCpuWidget(c.UpdateInterval, c.GraphHorizontalScale, c.AverageLoad, c.PercpuLoad)
|
||||
cpu := widgets.NewCPUWidget(c.UpdateInterval, c.GraphHorizontalScale, c.AverageLoad, c.PercpuLoad)
|
||||
assignColors(cpu.Data, c.Colorscheme.CPULines, cpu.LineColors)
|
||||
w = cpu
|
||||
case "mem":
|
||||
|
@ -228,7 +227,7 @@ func assignColors(data map[string][]float64, colors []int, assign map[string]ui.
|
|||
func countNumRows(rs [][]widgetRule) int {
|
||||
var ttl int
|
||||
for len(rs) > 0 {
|
||||
ttl += 1
|
||||
ttl++
|
||||
line := rs[0]
|
||||
h := 1
|
||||
for _, c := range line {
|
||||
|
|
|
@ -111,7 +111,7 @@ func ParseLayout(i io.Reader) layout {
|
|||
}
|
||||
weightTotal += weight
|
||||
} else {
|
||||
weightTotal += 1
|
||||
weightTotal++
|
||||
}
|
||||
row = append(row, wr)
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@ func TestLogging(t *testing.T) {
|
|||
defer os.RemoveAll(path)
|
||||
c := gotop.Config{
|
||||
MaxLogSize: 300,
|
||||
LogDir: path,
|
||||
LogFile: "errors.log",
|
||||
}
|
||||
wc, err := New(c)
|
||||
assert.NoError(t, err)
|
||||
|
@ -27,7 +25,7 @@ func TestLogging(t *testing.T) {
|
|||
}
|
||||
defer wc.Close()
|
||||
ds := make([]byte, 100)
|
||||
for i, _ := range ds {
|
||||
for i := range ds {
|
||||
ds[i] = 'x'
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
func ConvertLocalizedString(s string) string {
|
||||
if strings.ContainsAny(s, ",") {
|
||||
return strings.Replace(s, ",", ".", 1)
|
||||
} else {
|
||||
return s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ func (b *BatteryWidget) EnableMetric() {
|
|||
}
|
||||
}
|
||||
|
||||
func makeId(i int) string {
|
||||
func makeID(i int) string {
|
||||
return "Batt" + strconv.Itoa(i)
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ func (b *BatteryWidget) Scale(i int) {
|
|||
b.LineGraph.HorizontalScale = i
|
||||
}
|
||||
|
||||
func (self *BatteryWidget) update() {
|
||||
func (b *BatteryWidget) update() {
|
||||
batteries, err := battery.GetAll()
|
||||
if err != nil {
|
||||
switch errt := err.(type) {
|
||||
|
@ -94,13 +94,13 @@ func (self *BatteryWidget) update() {
|
|||
}
|
||||
}
|
||||
for i, battery := range batteries {
|
||||
id := makeId(i)
|
||||
id := makeID(i)
|
||||
perc := battery.Current / battery.Full
|
||||
percentFull := math.Abs(perc) * 100.0
|
||||
self.Data[id] = append(self.Data[id], percentFull)
|
||||
self.Labels[id] = fmt.Sprintf("%3.0f%% %.0f/%.0f", percentFull, math.Abs(battery.Current), math.Abs(battery.Full))
|
||||
if self.metric != nil {
|
||||
self.metric[i].Set(perc)
|
||||
b.Data[id] = append(b.Data[id], percentFull)
|
||||
b.Labels[id] = fmt.Sprintf("%3.0f%% %.0f/%.0f", percentFull, math.Abs(battery.Current), math.Abs(battery.Full))
|
||||
if b.metric != nil {
|
||||
b.metric[i].Set(perc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,16 +9,16 @@ import (
|
|||
"github.com/distatus/battery"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
. "github.com/xxxserxxx/gotop/v4/termui"
|
||||
"github.com/xxxserxxx/gotop/v4/termui"
|
||||
)
|
||||
|
||||
type BatteryGauge struct {
|
||||
*Gauge
|
||||
*termui.Gauge
|
||||
metric prometheus.Gauge
|
||||
}
|
||||
|
||||
func NewBatteryGauge() *BatteryGauge {
|
||||
self := &BatteryGauge{Gauge: NewGauge()}
|
||||
self := &BatteryGauge{Gauge: termui.NewGauge()}
|
||||
self.Title = " Power Level "
|
||||
|
||||
self.update()
|
||||
|
@ -56,7 +56,7 @@ func (b *BatteryGauge) EnableMetric() {
|
|||
}
|
||||
}
|
||||
|
||||
func (self *BatteryGauge) update() {
|
||||
func (b *BatteryGauge) update() {
|
||||
bats, err := battery.GetAll()
|
||||
if err != nil {
|
||||
log.Printf("error setting up batteries: %v", err)
|
||||
|
@ -78,9 +78,9 @@ func (self *BatteryGauge) update() {
|
|||
}
|
||||
tn := (mx - cu) / rate
|
||||
d, _ := time.ParseDuration(fmt.Sprintf("%fh", tn))
|
||||
self.Percent = int((cu / mx) * 100.0)
|
||||
self.Label = fmt.Sprintf(charging, self.Percent, d.Truncate(time.Minute))
|
||||
if self.metric != nil {
|
||||
self.metric.Set(cu / mx)
|
||||
b.Percent = int((cu / mx) * 100.0)
|
||||
b.Label = fmt.Sprintf(charging, b.Percent, d.Truncate(time.Minute))
|
||||
if b.metric != nil {
|
||||
b.metric.Set(cu / mx)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@ import (
|
|||
ui "github.com/xxxserxxx/gotop/v4/termui"
|
||||
)
|
||||
|
||||
type CpuWidget struct {
|
||||
type CPUWidget struct {
|
||||
*ui.LineGraph
|
||||
CpuCount int
|
||||
CPUCount int
|
||||
ShowAverageLoad bool
|
||||
ShowPerCpuLoad bool
|
||||
ShowPerCPULoad bool
|
||||
updateInterval time.Duration
|
||||
updateLock sync.Mutex
|
||||
metric map[string]prometheus.Gauge
|
||||
|
@ -24,20 +24,20 @@ type CpuWidget struct {
|
|||
|
||||
var cpuLabels []string
|
||||
|
||||
func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverageLoad bool, showPerCpuLoad bool) *CpuWidget {
|
||||
self := &CpuWidget{
|
||||
func NewCPUWidget(updateInterval time.Duration, horizontalScale int, showAverageLoad bool, showPerCPULoad bool) *CPUWidget {
|
||||
self := &CPUWidget{
|
||||
LineGraph: ui.NewLineGraph(),
|
||||
CpuCount: len(cpuLabels),
|
||||
CPUCount: len(cpuLabels),
|
||||
updateInterval: updateInterval,
|
||||
ShowAverageLoad: showAverageLoad,
|
||||
ShowPerCpuLoad: showPerCpuLoad,
|
||||
ShowPerCPULoad: showPerCPULoad,
|
||||
}
|
||||
self.Title = " CPU Usage "
|
||||
self.HorizontalScale = horizontalScale
|
||||
|
||||
if !(self.ShowAverageLoad || self.ShowPerCpuLoad) {
|
||||
if self.CpuCount <= 8 {
|
||||
self.ShowPerCpuLoad = true
|
||||
if !(self.ShowAverageLoad || self.ShowPerCPULoad) {
|
||||
if self.CPUCount <= 8 {
|
||||
self.ShowPerCPULoad = true
|
||||
} else {
|
||||
self.ShowAverageLoad = true
|
||||
}
|
||||
|
@ -47,9 +47,9 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage
|
|||
self.Data["AVRG"] = []float64{0}
|
||||
}
|
||||
|
||||
if self.ShowPerCpuLoad {
|
||||
if self.ShowPerCPULoad {
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCPULoad)
|
||||
for k, v := range cpus {
|
||||
self.Data[k] = []float64{float64(v)}
|
||||
}
|
||||
|
@ -66,17 +66,17 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage
|
|||
return self
|
||||
}
|
||||
|
||||
func (self *CpuWidget) EnableMetric() {
|
||||
if self.ShowAverageLoad {
|
||||
self.metric = make(map[string]prometheus.Gauge)
|
||||
self.metric["AVRG"] = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
func (cpu *CPUWidget) EnableMetric() {
|
||||
if cpu.ShowAverageLoad {
|
||||
cpu.metric = make(map[string]prometheus.Gauge)
|
||||
cpu.metric["AVRG"] = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Subsystem: "cpu",
|
||||
Name: "avg",
|
||||
})
|
||||
} else {
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad)
|
||||
self.metric = make(map[string]prometheus.Gauge)
|
||||
devices.UpdateCPU(cpus, cpu.updateInterval, cpu.ShowPerCPULoad)
|
||||
cpu.metric = make(map[string]prometheus.Gauge)
|
||||
for key, perc := range cpus {
|
||||
gauge := prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "gotop",
|
||||
|
@ -85,53 +85,53 @@ func (self *CpuWidget) EnableMetric() {
|
|||
})
|
||||
gauge.Set(float64(perc))
|
||||
prometheus.MustRegister(gauge)
|
||||
self.metric[key] = gauge
|
||||
cpu.metric[key] = gauge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *CpuWidget) Scale(i int) {
|
||||
b.LineGraph.HorizontalScale = i
|
||||
func (cpu *CPUWidget) Scale(i int) {
|
||||
cpu.LineGraph.HorizontalScale = i
|
||||
}
|
||||
|
||||
func (self *CpuWidget) update() {
|
||||
if self.ShowAverageLoad {
|
||||
func (cpu *CPUWidget) update() {
|
||||
if cpu.ShowAverageLoad {
|
||||
go func() {
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, false)
|
||||
self.Lock()
|
||||
defer self.Unlock()
|
||||
self.updateLock.Lock()
|
||||
defer self.updateLock.Unlock()
|
||||
devices.UpdateCPU(cpus, cpu.updateInterval, false)
|
||||
cpu.Lock()
|
||||
defer cpu.Unlock()
|
||||
cpu.updateLock.Lock()
|
||||
defer cpu.updateLock.Unlock()
|
||||
var val float64
|
||||
for _, v := range cpus {
|
||||
val = float64(v)
|
||||
break
|
||||
}
|
||||
self.Data["AVRG"] = append(self.Data["AVRG"], val)
|
||||
self.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", val)
|
||||
if self.metric != nil {
|
||||
self.metric["AVRG"].Set(val)
|
||||
cpu.Data["AVRG"] = append(cpu.Data["AVRG"], val)
|
||||
cpu.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", val)
|
||||
if cpu.metric != nil {
|
||||
cpu.metric["AVRG"].Set(val)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if self.ShowPerCpuLoad {
|
||||
if cpu.ShowPerCPULoad {
|
||||
go func() {
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, true)
|
||||
self.Lock()
|
||||
defer self.Unlock()
|
||||
self.updateLock.Lock()
|
||||
defer self.updateLock.Unlock()
|
||||
devices.UpdateCPU(cpus, cpu.updateInterval, true)
|
||||
cpu.Lock()
|
||||
defer cpu.Unlock()
|
||||
cpu.updateLock.Lock()
|
||||
defer cpu.updateLock.Unlock()
|
||||
for key, percent := range cpus {
|
||||
self.Data[key] = append(self.Data[key], float64(percent))
|
||||
self.Labels[key] = fmt.Sprintf("%d%%", percent)
|
||||
if self.metric != nil {
|
||||
if self.metric[key] == nil {
|
||||
cpu.Data[key] = append(cpu.Data[key], float64(percent))
|
||||
cpu.Labels[key] = fmt.Sprintf("%d%%", percent)
|
||||
if cpu.metric != nil {
|
||||
if cpu.metric[key] == nil {
|
||||
log.Printf("no metrics for %s", key)
|
||||
} else {
|
||||
self.metric[key].Set(float64(percent))
|
||||
cpu.metric[key].Set(float64(percent))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,9 +64,9 @@ func NewDiskWidget() *DiskWidget {
|
|||
return self
|
||||
}
|
||||
|
||||
func (self *DiskWidget) EnableMetric() {
|
||||
self.metric = make(map[string]prometheus.Gauge)
|
||||
for key, part := range self.Partitions {
|
||||
func (disk *DiskWidget) EnableMetric() {
|
||||
disk.metric = make(map[string]prometheus.Gauge)
|
||||
for key, part := range disk.Partitions {
|
||||
gauge := prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "gotop",
|
||||
Subsystem: "disk",
|
||||
|
@ -75,11 +75,11 @@ func (self *DiskWidget) EnableMetric() {
|
|||
})
|
||||
gauge.Set(float64(part.UsedPercent) / 100.0)
|
||||
prometheus.MustRegister(gauge)
|
||||
self.metric[key] = gauge
|
||||
disk.metric[key] = gauge
|
||||
}
|
||||
}
|
||||
|
||||
func (self *DiskWidget) update() {
|
||||
func (disk *DiskWidget) update() {
|
||||
partitions, err := psDisk.Partitions(false)
|
||||
if err != nil {
|
||||
log.Printf("failed to get disk partitions from gopsutil: %v", err)
|
||||
|
@ -97,8 +97,8 @@ func (self *DiskWidget) update() {
|
|||
continue
|
||||
}
|
||||
// check if partition doesn't already exist in our list
|
||||
if _, ok := self.Partitions[partition.Device]; !ok {
|
||||
self.Partitions[partition.Device] = &Partition{
|
||||
if _, ok := disk.Partitions[partition.Device]; !ok {
|
||||
disk.Partitions[partition.Device] = &Partition{
|
||||
Device: partition.Device,
|
||||
MountPoint: partition.Mountpoint,
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func (self *DiskWidget) update() {
|
|||
|
||||
// delete a partition if it no longer exists
|
||||
toDelete := []string{}
|
||||
for device := range self.Partitions {
|
||||
for device := range disk.Partitions {
|
||||
exists := false
|
||||
for _, partition := range partitions {
|
||||
if device == partition.Device {
|
||||
|
@ -120,11 +120,11 @@ func (self *DiskWidget) update() {
|
|||
}
|
||||
}
|
||||
for _, device := range toDelete {
|
||||
delete(self.Partitions, device)
|
||||
delete(disk.Partitions, device)
|
||||
}
|
||||
|
||||
// updates partition info. We add 0.5 to all values to make sure the truncation rounds
|
||||
for _, partition := range self.Partitions {
|
||||
for _, partition := range disk.Partitions {
|
||||
usage, err := psDisk.Usage(partition.MountPoint)
|
||||
if err != nil {
|
||||
log.Printf("failed to get partition usage statistics from gopsutil: %v. partition: %v", err, partition)
|
||||
|
@ -160,27 +160,27 @@ func (self *DiskWidget) update() {
|
|||
// converts self.Partitions into self.Rows which is a [][]String
|
||||
|
||||
sortedPartitions := []string{}
|
||||
for seriesName := range self.Partitions {
|
||||
for seriesName := range disk.Partitions {
|
||||
sortedPartitions = append(sortedPartitions, seriesName)
|
||||
}
|
||||
sort.Strings(sortedPartitions)
|
||||
|
||||
self.Rows = make([][]string, len(self.Partitions))
|
||||
disk.Rows = make([][]string, len(disk.Partitions))
|
||||
|
||||
for i, key := range sortedPartitions {
|
||||
partition := self.Partitions[key]
|
||||
self.Rows[i] = make([]string, 6)
|
||||
self.Rows[i][0] = strings.Replace(strings.Replace(partition.Device, "/dev/", "", -1), "mapper/", "", -1)
|
||||
self.Rows[i][1] = partition.MountPoint
|
||||
self.Rows[i][2] = fmt.Sprintf("%d%%", partition.UsedPercent)
|
||||
self.Rows[i][3] = partition.Free
|
||||
self.Rows[i][4] = partition.BytesReadRecently
|
||||
self.Rows[i][5] = partition.BytesWrittenRecently
|
||||
if self.metric != nil {
|
||||
if self.metric[key] == nil {
|
||||
partition := disk.Partitions[key]
|
||||
disk.Rows[i] = make([]string, 6)
|
||||
disk.Rows[i][0] = strings.Replace(strings.Replace(partition.Device, "/dev/", "", -1), "mapper/", "", -1)
|
||||
disk.Rows[i][1] = partition.MountPoint
|
||||
disk.Rows[i][2] = fmt.Sprintf("%d%%", partition.UsedPercent)
|
||||
disk.Rows[i][3] = partition.Free
|
||||
disk.Rows[i][4] = partition.BytesReadRecently
|
||||
disk.Rows[i][5] = partition.BytesWrittenRecently
|
||||
if disk.metric != nil {
|
||||
if disk.metric[key] == nil {
|
||||
log.Printf("ERROR: missing metric %s", key)
|
||||
} else {
|
||||
self.metric[key].Set(float64(partition.UsedPercent) / 100.0)
|
||||
disk.metric[key].Set(float64(partition.UsedPercent) / 100.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
ui "github.com/gizak/termui/v3"
|
||||
)
|
||||
|
||||
// KEYBINDS is the help text for the in-program shortcuts
|
||||
const KEYBINDS = `
|
||||
Quit: q or <C-c>
|
||||
|
||||
|
@ -55,7 +56,7 @@ func NewHelpMenu() *HelpMenu {
|
|||
}
|
||||
}
|
||||
|
||||
func (self *HelpMenu) Resize(termWidth, termHeight int) {
|
||||
func (help *HelpMenu) Resize(termWidth, termHeight int) {
|
||||
textWidth := 53
|
||||
for _, line := range strings.Split(KEYBINDS, "\n") {
|
||||
if textWidth < len(line) {
|
||||
|
@ -66,17 +67,17 @@ func (self *HelpMenu) Resize(termWidth, termHeight int) {
|
|||
x := (termWidth - textWidth) / 2
|
||||
y := (termHeight - textHeight) / 2
|
||||
|
||||
self.Block.SetRect(x, y, textWidth+x, textHeight+y)
|
||||
help.Block.SetRect(x, y, textWidth+x, textHeight+y)
|
||||
}
|
||||
|
||||
func (self *HelpMenu) Draw(buf *ui.Buffer) {
|
||||
self.Block.Draw(buf)
|
||||
func (help *HelpMenu) Draw(buf *ui.Buffer) {
|
||||
help.Block.Draw(buf)
|
||||
|
||||
for y, line := range strings.Split(KEYBINDS, "\n") {
|
||||
for x, rune := range line {
|
||||
buf.SetCell(
|
||||
ui.NewCell(rune, ui.Theme.Default),
|
||||
image.Pt(self.Inner.Min.X+x, self.Inner.Min.Y+y-1),
|
||||
image.Pt(help.Inner.Min.X+x, help.Inner.Min.Y+y-1),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,30 +48,30 @@ func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget
|
|||
return self
|
||||
}
|
||||
|
||||
func (b *MemWidget) EnableMetric() {
|
||||
b.metrics = make(map[string]prometheus.Gauge)
|
||||
func (mem *MemWidget) EnableMetric() {
|
||||
mem.metrics = make(map[string]prometheus.Gauge)
|
||||
mems := make(map[string]devices.MemoryInfo)
|
||||
devices.UpdateMem(mems)
|
||||
for l, mem := range mems {
|
||||
b.metrics[l] = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
for l, m := range mems {
|
||||
mem.metrics[l] = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "gotop",
|
||||
Subsystem: "memory",
|
||||
Name: l,
|
||||
})
|
||||
b.metrics[l].Set(mem.UsedPercent)
|
||||
prometheus.MustRegister(b.metrics[l])
|
||||
mem.metrics[l].Set(m.UsedPercent)
|
||||
prometheus.MustRegister(mem.metrics[l])
|
||||
}
|
||||
}
|
||||
|
||||
func (b *MemWidget) Scale(i int) {
|
||||
b.LineGraph.HorizontalScale = i
|
||||
func (mem *MemWidget) Scale(i int) {
|
||||
mem.LineGraph.HorizontalScale = i
|
||||
}
|
||||
|
||||
func (self *MemWidget) renderMemInfo(line string, memoryInfo devices.MemoryInfo) {
|
||||
self.Data[line] = append(self.Data[line], memoryInfo.UsedPercent)
|
||||
func (mem *MemWidget) renderMemInfo(line string, memoryInfo devices.MemoryInfo) {
|
||||
mem.Data[line] = append(mem.Data[line], memoryInfo.UsedPercent)
|
||||
memoryTotalBytes, memoryTotalMagnitude := utils.ConvertBytes(memoryInfo.Total)
|
||||
memoryUsedBytes, memoryUsedMagnitude := utils.ConvertBytes(memoryInfo.Used)
|
||||
self.Labels[line] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s",
|
||||
mem.Labels[line] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s",
|
||||
memoryInfo.UsedPercent,
|
||||
memoryUsedBytes,
|
||||
memoryUsedMagnitude,
|
||||
|
|
|
@ -14,8 +14,10 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
NET_INTERFACE_ALL = "all"
|
||||
NET_INTERFACE_VPN = "tun0"
|
||||
// NetInterfaceAll enables all network interfaces
|
||||
NetInterfaceAll = "all"
|
||||
// NetInterfaceVpn is the VPN interface
|
||||
NetInterfaceVpn = "tun0"
|
||||
)
|
||||
|
||||
type NetWidget struct {
|
||||
|
@ -63,23 +65,23 @@ func NewNetWidget(netInterface string) *NetWidget {
|
|||
return self
|
||||
}
|
||||
|
||||
func (b *NetWidget) EnableMetric() {
|
||||
b.recvMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
func (net *NetWidget) EnableMetric() {
|
||||
net.recvMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: "gotop",
|
||||
Subsystem: "net",
|
||||
Name: "recv",
|
||||
})
|
||||
prometheus.MustRegister(b.recvMetric)
|
||||
prometheus.MustRegister(net.recvMetric)
|
||||
|
||||
b.sentMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
net.sentMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: "gotop",
|
||||
Subsystem: "net",
|
||||
Name: "sent",
|
||||
})
|
||||
prometheus.MustRegister(b.sentMetric)
|
||||
prometheus.MustRegister(net.sentMetric)
|
||||
}
|
||||
|
||||
func (self *NetWidget) update() {
|
||||
func (net *NetWidget) update() {
|
||||
interfaces, err := psNet.IOCounters(true)
|
||||
if err != nil {
|
||||
log.Printf("failed to get network activity from gopsutil: %v", err)
|
||||
|
@ -90,15 +92,15 @@ func (self *NetWidget) update() {
|
|||
var totalBytesSent uint64
|
||||
interfaceMap := make(map[string]bool)
|
||||
// Default behaviour
|
||||
interfaceMap[NET_INTERFACE_ALL] = true
|
||||
interfaceMap[NET_INTERFACE_VPN] = false
|
||||
interfaceMap[NetInterfaceAll] = true
|
||||
interfaceMap[NetInterfaceVpn] = false
|
||||
// Build a map with wanted status for each interfaces.
|
||||
for _, iface := range self.NetInterface {
|
||||
for _, iface := range net.NetInterface {
|
||||
if strings.HasPrefix(iface, "!") {
|
||||
interfaceMap[strings.TrimPrefix(iface, "!")] = false
|
||||
} else {
|
||||
// if we specify a wanted interface, remove capture on all.
|
||||
delete(interfaceMap, NET_INTERFACE_ALL)
|
||||
delete(interfaceMap, NetInterfaceAll)
|
||||
interfaceMap[iface] = true
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +111,7 @@ func (self *NetWidget) update() {
|
|||
totalBytesSent += _interface.BytesSent
|
||||
} else if ok { // Present but unwanted
|
||||
continue
|
||||
} else if interfaceMap[NET_INTERFACE_ALL] { // Capture other
|
||||
} else if interfaceMap[NetInterfaceAll] { // Capture other
|
||||
totalBytesRecv += _interface.BytesRecv
|
||||
totalBytesSent += _interface.BytesSent
|
||||
}
|
||||
|
@ -118,9 +120,9 @@ func (self *NetWidget) update() {
|
|||
var recentBytesRecv uint64
|
||||
var recentBytesSent uint64
|
||||
|
||||
if self.totalBytesRecv != 0 { // if this isn't the first update
|
||||
recentBytesRecv = totalBytesRecv - self.totalBytesRecv
|
||||
recentBytesSent = totalBytesSent - self.totalBytesSent
|
||||
if net.totalBytesRecv != 0 { // if this isn't the first update
|
||||
recentBytesRecv = totalBytesRecv - net.totalBytesRecv
|
||||
recentBytesSent = totalBytesSent - net.totalBytesSent
|
||||
|
||||
if int(recentBytesRecv) < 0 {
|
||||
log.Printf("error: negative value for recently received network data from gopsutil. recentBytesRecv: %v", recentBytesRecv)
|
||||
|
@ -133,20 +135,20 @@ func (self *NetWidget) update() {
|
|||
recentBytesSent = 0
|
||||
}
|
||||
|
||||
self.Lines[0].Data = append(self.Lines[0].Data, int(recentBytesRecv))
|
||||
self.Lines[1].Data = append(self.Lines[1].Data, int(recentBytesSent))
|
||||
if self.sentMetric != nil {
|
||||
self.sentMetric.Add(float64(recentBytesSent))
|
||||
self.recvMetric.Add(float64(recentBytesRecv))
|
||||
net.Lines[0].Data = append(net.Lines[0].Data, int(recentBytesRecv))
|
||||
net.Lines[1].Data = append(net.Lines[1].Data, int(recentBytesSent))
|
||||
if net.sentMetric != nil {
|
||||
net.sentMetric.Add(float64(recentBytesSent))
|
||||
net.recvMetric.Add(float64(recentBytesRecv))
|
||||
}
|
||||
}
|
||||
|
||||
// used in later calls to update
|
||||
self.totalBytesRecv = totalBytesRecv
|
||||
self.totalBytesSent = totalBytesSent
|
||||
net.totalBytesRecv = totalBytesRecv
|
||||
net.totalBytesSent = totalBytesSent
|
||||
|
||||
rx, tx := "RX/s", "TX/s"
|
||||
if self.Mbps {
|
||||
if net.Mbps {
|
||||
rx, tx = "mbps", "mbps"
|
||||
}
|
||||
format := " %s: %9.1f %2s/s"
|
||||
|
@ -163,13 +165,13 @@ func (self *NetWidget) update() {
|
|||
}
|
||||
|
||||
totalConverted, unitTotal := utils.ConvertBytes(total)
|
||||
if self.Mbps {
|
||||
if net.Mbps {
|
||||
recentConverted, unitRecent, format = float64(recent)*0.000008, "", " %s: %11.3f %2s"
|
||||
} else {
|
||||
recentConverted, unitRecent = utils.ConvertBytes(recent)
|
||||
}
|
||||
|
||||
self.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", label, totalConverted, unitTotal)
|
||||
self.Lines[i].Title2 = fmt.Sprintf(format, rate, recentConverted, unitRecent)
|
||||
net.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", label, totalConverted, unitTotal)
|
||||
net.Lines[i].Title2 = fmt.Sprintf(format, rate, recentConverted, unitRecent)
|
||||
}
|
||||
}
|
||||
|
|
175
widgets/proc.go
175
widgets/proc.go
|
@ -17,14 +17,13 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
UP_ARROW = "▲"
|
||||
DOWN_ARROW = "▼"
|
||||
_downArrow = "▼"
|
||||
)
|
||||
|
||||
type ProcSortMethod string
|
||||
|
||||
const (
|
||||
ProcSortCpu ProcSortMethod = "c"
|
||||
ProcSortCPU ProcSortMethod = "c"
|
||||
ProcSortMem = "m"
|
||||
ProcSortPid = "p"
|
||||
)
|
||||
|
@ -33,7 +32,7 @@ type Proc struct {
|
|||
Pid int
|
||||
CommandName string
|
||||
FullCommand string
|
||||
Cpu float64
|
||||
CPU float64
|
||||
Mem float64
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ func NewProcWidget() *ProcWidget {
|
|||
Table: ui.NewTable(),
|
||||
updateInterval: time.Second,
|
||||
cpuCount: cpuCount,
|
||||
sortMethod: ProcSortCpu,
|
||||
sortMethod: ProcSortCPU,
|
||||
showGroupedProcs: true,
|
||||
filter: "",
|
||||
}
|
||||
|
@ -100,42 +99,42 @@ func NewProcWidget() *ProcWidget {
|
|||
return self
|
||||
}
|
||||
|
||||
func (p *ProcWidget) EnableMetric() {
|
||||
func (proc *ProcWidget) EnableMetric() {
|
||||
// There's (currently) no metric for this
|
||||
}
|
||||
|
||||
func (self *ProcWidget) SetEditingFilter(editing bool) {
|
||||
self.entry.SetEditing(editing)
|
||||
func (proc *ProcWidget) SetEditingFilter(editing bool) {
|
||||
proc.entry.SetEditing(editing)
|
||||
}
|
||||
|
||||
func (self *ProcWidget) HandleEvent(e tui.Event) bool {
|
||||
return self.entry.HandleEvent(e)
|
||||
func (proc *ProcWidget) HandleEvent(e tui.Event) bool {
|
||||
return proc.entry.HandleEvent(e)
|
||||
}
|
||||
|
||||
func (self *ProcWidget) SetRect(x1, y1, x2, y2 int) {
|
||||
self.Table.SetRect(x1, y1, x2, y2)
|
||||
self.entry.SetRect(x1+2, y2-1, x2-2, y2)
|
||||
func (proc *ProcWidget) SetRect(x1, y1, x2, y2 int) {
|
||||
proc.Table.SetRect(x1, y1, x2, y2)
|
||||
proc.entry.SetRect(x1+2, y2-1, x2-2, y2)
|
||||
}
|
||||
|
||||
func (self *ProcWidget) Draw(buf *tui.Buffer) {
|
||||
self.Table.Draw(buf)
|
||||
self.entry.Draw(buf)
|
||||
func (proc *ProcWidget) Draw(buf *tui.Buffer) {
|
||||
proc.Table.Draw(buf)
|
||||
proc.entry.Draw(buf)
|
||||
}
|
||||
|
||||
func (self *ProcWidget) filterProcs(procs []Proc) []Proc {
|
||||
if self.filter == "" {
|
||||
func (proc *ProcWidget) filterProcs(procs []Proc) []Proc {
|
||||
if proc.filter == "" {
|
||||
return procs
|
||||
}
|
||||
var filtered []Proc
|
||||
for _, proc := range procs {
|
||||
if strings.Contains(proc.FullCommand, self.filter) || strings.Contains(fmt.Sprintf("%d", proc.Pid), self.filter) {
|
||||
filtered = append(filtered, proc)
|
||||
for _, p := range procs {
|
||||
if strings.Contains(p.FullCommand, proc.filter) || strings.Contains(fmt.Sprintf("%d", p.Pid), proc.filter) {
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func (self *ProcWidget) update() {
|
||||
func (proc *ProcWidget) update() {
|
||||
procs, err := getProcs()
|
||||
if err != nil {
|
||||
log.Printf("failed to retrieve processes: %v", err)
|
||||
|
@ -144,103 +143,103 @@ func (self *ProcWidget) update() {
|
|||
|
||||
// have to iterate over the entry number in order to modify the array in place
|
||||
for i := range procs {
|
||||
procs[i].Cpu /= float64(self.cpuCount)
|
||||
procs[i].CPU /= float64(proc.cpuCount)
|
||||
}
|
||||
|
||||
procs = self.filterProcs(procs)
|
||||
self.ungroupedProcs = procs
|
||||
self.groupedProcs = groupProcs(procs)
|
||||
procs = proc.filterProcs(procs)
|
||||
proc.ungroupedProcs = procs
|
||||
proc.groupedProcs = groupProcs(procs)
|
||||
|
||||
self.sortProcs()
|
||||
self.convertProcsToTableRows()
|
||||
proc.sortProcs()
|
||||
proc.convertProcsToTableRows()
|
||||
}
|
||||
|
||||
// sortProcs sorts either the grouped or ungrouped []Process based on the sortMethod.
|
||||
// Called with every update, when the sort method is changed, and when processes are grouped and ungrouped.
|
||||
func (self *ProcWidget) sortProcs() {
|
||||
self.Header = []string{"Count", "Command", "CPU%", "Mem%"}
|
||||
func (proc *ProcWidget) sortProcs() {
|
||||
proc.Header = []string{"Count", "Command", "CPU%", "Mem%"}
|
||||
|
||||
if !self.showGroupedProcs {
|
||||
self.Header[0] = "PID"
|
||||
if !proc.showGroupedProcs {
|
||||
proc.Header[0] = "PID"
|
||||
}
|
||||
|
||||
var procs *[]Proc
|
||||
if self.showGroupedProcs {
|
||||
procs = &self.groupedProcs
|
||||
if proc.showGroupedProcs {
|
||||
procs = &proc.groupedProcs
|
||||
} else {
|
||||
procs = &self.ungroupedProcs
|
||||
procs = &proc.ungroupedProcs
|
||||
}
|
||||
|
||||
switch self.sortMethod {
|
||||
case ProcSortCpu:
|
||||
sort.Sort(sort.Reverse(SortProcsByCpu(*procs)))
|
||||
self.Header[2] += DOWN_ARROW
|
||||
switch proc.sortMethod {
|
||||
case ProcSortCPU:
|
||||
sort.Sort(sort.Reverse(SortProcsByCPU(*procs)))
|
||||
proc.Header[2] += _downArrow
|
||||
case ProcSortPid:
|
||||
if self.showGroupedProcs {
|
||||
if proc.showGroupedProcs {
|
||||
sort.Sort(sort.Reverse(SortProcsByPid(*procs)))
|
||||
} else {
|
||||
sort.Sort(SortProcsByPid(*procs))
|
||||
}
|
||||
self.Header[0] += DOWN_ARROW
|
||||
proc.Header[0] += _downArrow
|
||||
case ProcSortMem:
|
||||
sort.Sort(sort.Reverse(SortProcsByMem(*procs)))
|
||||
self.Header[3] += DOWN_ARROW
|
||||
proc.Header[3] += _downArrow
|
||||
}
|
||||
}
|
||||
|
||||
// convertProcsToTableRows converts a []Proc to a [][]string and sets it to the table Rows
|
||||
func (self *ProcWidget) convertProcsToTableRows() {
|
||||
func (proc *ProcWidget) convertProcsToTableRows() {
|
||||
var procs *[]Proc
|
||||
if self.showGroupedProcs {
|
||||
procs = &self.groupedProcs
|
||||
if proc.showGroupedProcs {
|
||||
procs = &proc.groupedProcs
|
||||
} else {
|
||||
procs = &self.ungroupedProcs
|
||||
procs = &proc.ungroupedProcs
|
||||
}
|
||||
strings := make([][]string, len(*procs))
|
||||
for i := range *procs {
|
||||
strings[i] = make([]string, 4)
|
||||
strings[i][0] = strconv.Itoa(int((*procs)[i].Pid))
|
||||
if self.showGroupedProcs {
|
||||
if proc.showGroupedProcs {
|
||||
strings[i][1] = (*procs)[i].CommandName
|
||||
} else {
|
||||
strings[i][1] = (*procs)[i].FullCommand
|
||||
}
|
||||
strings[i][2] = fmt.Sprintf("%4s", strconv.FormatFloat((*procs)[i].Cpu, 'f', 1, 64))
|
||||
strings[i][2] = fmt.Sprintf("%4s", strconv.FormatFloat((*procs)[i].CPU, 'f', 1, 64))
|
||||
strings[i][3] = fmt.Sprintf("%4s", strconv.FormatFloat(float64((*procs)[i].Mem), 'f', 1, 64))
|
||||
}
|
||||
self.Rows = strings
|
||||
proc.Rows = strings
|
||||
}
|
||||
|
||||
func (self *ProcWidget) ChangeProcSortMethod(method ProcSortMethod) {
|
||||
if self.sortMethod != method {
|
||||
self.sortMethod = method
|
||||
self.ScrollTop()
|
||||
self.sortProcs()
|
||||
self.convertProcsToTableRows()
|
||||
func (proc *ProcWidget) ChangeProcSortMethod(method ProcSortMethod) {
|
||||
if proc.sortMethod != method {
|
||||
proc.sortMethod = method
|
||||
proc.ScrollTop()
|
||||
proc.sortProcs()
|
||||
proc.convertProcsToTableRows()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *ProcWidget) ToggleShowingGroupedProcs() {
|
||||
self.showGroupedProcs = !self.showGroupedProcs
|
||||
if self.showGroupedProcs {
|
||||
self.UniqueCol = 1
|
||||
func (proc *ProcWidget) ToggleShowingGroupedProcs() {
|
||||
proc.showGroupedProcs = !proc.showGroupedProcs
|
||||
if proc.showGroupedProcs {
|
||||
proc.UniqueCol = 1
|
||||
} else {
|
||||
self.UniqueCol = 0
|
||||
proc.UniqueCol = 0
|
||||
}
|
||||
self.ScrollTop()
|
||||
self.sortProcs()
|
||||
self.convertProcsToTableRows()
|
||||
proc.ScrollTop()
|
||||
proc.sortProcs()
|
||||
proc.convertProcsToTableRows()
|
||||
}
|
||||
|
||||
// KillProc kills a process or group of processes depending on if we're
|
||||
// displaying the processes grouped or not.
|
||||
func (self *ProcWidget) KillProc(sigName string) {
|
||||
self.SelectedItem = ""
|
||||
func (proc *ProcWidget) KillProc(sigName string) {
|
||||
proc.SelectedItem = ""
|
||||
command := "kill"
|
||||
if self.UniqueCol == 1 {
|
||||
if proc.UniqueCol == 1 {
|
||||
command = "pkill"
|
||||
}
|
||||
cmd := exec.Command(command, "--signal", sigName, self.Rows[self.SelectedRow][self.UniqueCol])
|
||||
cmd := exec.Command(command, "--signal", sigName, proc.Rows[proc.SelectedRow][proc.UniqueCol])
|
||||
cmd.Start()
|
||||
cmd.Wait()
|
||||
}
|
||||
|
@ -257,7 +256,7 @@ func groupProcs(procs []Proc) []Proc {
|
|||
val.Pid + 1,
|
||||
val.CommandName,
|
||||
"",
|
||||
val.Cpu + proc.Cpu,
|
||||
val.CPU + proc.CPU,
|
||||
val.Mem + proc.Mem,
|
||||
}
|
||||
} else {
|
||||
|
@ -265,7 +264,7 @@ func groupProcs(procs []Proc) []Proc {
|
|||
1,
|
||||
proc.CommandName,
|
||||
"",
|
||||
proc.Cpu,
|
||||
proc.CPU,
|
||||
proc.Mem,
|
||||
}
|
||||
}
|
||||
|
@ -283,53 +282,53 @@ func groupProcs(procs []Proc) []Proc {
|
|||
|
||||
// []Proc Sorting //////////////////////////////////////////////////////////////
|
||||
|
||||
type SortProcsByCpu []Proc
|
||||
type SortProcsByCPU []Proc
|
||||
|
||||
// Len implements Sort interface
|
||||
func (self SortProcsByCpu) Len() int {
|
||||
return len(self)
|
||||
func (procs SortProcsByCPU) Len() int {
|
||||
return len(procs)
|
||||
}
|
||||
|
||||
// Swap implements Sort interface
|
||||
func (self SortProcsByCpu) Swap(i, j int) {
|
||||
self[i], self[j] = self[j], self[i]
|
||||
func (procs SortProcsByCPU) Swap(i, j int) {
|
||||
procs[i], procs[j] = procs[j], procs[i]
|
||||
}
|
||||
|
||||
// Less implements Sort interface
|
||||
func (self SortProcsByCpu) Less(i, j int) bool {
|
||||
return self[i].Cpu < self[j].Cpu
|
||||
func (procs SortProcsByCPU) Less(i, j int) bool {
|
||||
return procs[i].CPU < procs[j].CPU
|
||||
}
|
||||
|
||||
type SortProcsByPid []Proc
|
||||
|
||||
// Len implements Sort interface
|
||||
func (self SortProcsByPid) Len() int {
|
||||
return len(self)
|
||||
func (procs SortProcsByPid) Len() int {
|
||||
return len(procs)
|
||||
}
|
||||
|
||||
// Swap implements Sort interface
|
||||
func (self SortProcsByPid) Swap(i, j int) {
|
||||
self[i], self[j] = self[j], self[i]
|
||||
func (procs SortProcsByPid) Swap(i, j int) {
|
||||
procs[i], procs[j] = procs[j], procs[i]
|
||||
}
|
||||
|
||||
// Less implements Sort interface
|
||||
func (self SortProcsByPid) Less(i, j int) bool {
|
||||
return self[i].Pid < self[j].Pid
|
||||
func (procs SortProcsByPid) Less(i, j int) bool {
|
||||
return procs[i].Pid < procs[j].Pid
|
||||
}
|
||||
|
||||
type SortProcsByMem []Proc
|
||||
|
||||
// Len implements Sort interface
|
||||
func (self SortProcsByMem) Len() int {
|
||||
return len(self)
|
||||
func (procs SortProcsByMem) Len() int {
|
||||
return len(procs)
|
||||
}
|
||||
|
||||
// Swap implements Sort interface
|
||||
func (self SortProcsByMem) Swap(i, j int) {
|
||||
self[i], self[j] = self[j], self[i]
|
||||
func (procs SortProcsByMem) Swap(i, j int) {
|
||||
procs[i], procs[j] = procs[j], procs[i]
|
||||
}
|
||||
|
||||
// Less implements Sort interface
|
||||
func (self SortProcsByMem) Less(i, j int) bool {
|
||||
return self[i].Mem < self[j].Mem
|
||||
func (procs SortProcsByMem) Less(i, j int) bool {
|
||||
return procs[i].Mem < procs[j].Mem
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func getProcs() ([]Proc, error) {
|
|||
Pid: pid,
|
||||
CommandName: strings.TrimSpace(line[11:61]),
|
||||
FullCommand: line[74:],
|
||||
Cpu: cpu,
|
||||
CPU: cpu,
|
||||
Mem: mem,
|
||||
}
|
||||
procs = append(procs, proc)
|
||||
|
|
|
@ -19,8 +19,8 @@ func NewStatusBar() *StatusBar {
|
|||
return self
|
||||
}
|
||||
|
||||
func (self *StatusBar) Draw(buf *ui.Buffer) {
|
||||
self.Block.Draw(buf)
|
||||
func (sb *StatusBar) Draw(buf *ui.Buffer) {
|
||||
sb.Block.Draw(buf)
|
||||
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
|
@ -30,7 +30,7 @@ func (self *StatusBar) Draw(buf *ui.Buffer) {
|
|||
buf.SetString(
|
||||
hostname,
|
||||
ui.Theme.Default,
|
||||
image.Pt(self.Inner.Min.X, self.Inner.Min.Y+(self.Inner.Dy()/2)),
|
||||
image.Pt(sb.Inner.Min.X, sb.Inner.Min.Y+(sb.Inner.Dy()/2)),
|
||||
)
|
||||
|
||||
currentTime := time.Now()
|
||||
|
@ -39,8 +39,8 @@ func (self *StatusBar) Draw(buf *ui.Buffer) {
|
|||
formattedTime,
|
||||
ui.Theme.Default,
|
||||
image.Pt(
|
||||
self.Inner.Min.X+(self.Inner.Dx()/2)-len(formattedTime)/2,
|
||||
self.Inner.Min.Y+(self.Inner.Dy()/2),
|
||||
sb.Inner.Min.X+(sb.Inner.Dx()/2)-len(formattedTime)/2,
|
||||
sb.Inner.Min.Y+(sb.Inner.Dy()/2),
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -48,8 +48,8 @@ func (self *StatusBar) Draw(buf *ui.Buffer) {
|
|||
"gotop",
|
||||
ui.Theme.Default,
|
||||
image.Pt(
|
||||
self.Inner.Max.X-6,
|
||||
self.Inner.Min.Y+(self.Inner.Dy()/2),
|
||||
sb.Inner.Max.X-6,
|
||||
sb.Inner.Min.Y+(sb.Inner.Dy()/2),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -68,9 +68,9 @@ func NewTempWidget(tempScale TempScale, filter []string) *TempWidget {
|
|||
return self
|
||||
}
|
||||
|
||||
func (self *TempWidget) EnableMetric() {
|
||||
self.tempsMetric = make(map[string]prometheus.Gauge)
|
||||
for k, v := range self.Data {
|
||||
func (temp *TempWidget) EnableMetric() {
|
||||
temp.tempsMetric = make(map[string]prometheus.Gauge)
|
||||
for k, v := range temp.Data {
|
||||
gauge := prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "gotop",
|
||||
Subsystem: "temp",
|
||||
|
@ -78,58 +78,58 @@ func (self *TempWidget) EnableMetric() {
|
|||
})
|
||||
gauge.Set(float64(v))
|
||||
prometheus.MustRegister(gauge)
|
||||
self.tempsMetric[k] = gauge
|
||||
temp.tempsMetric[k] = gauge
|
||||
}
|
||||
}
|
||||
|
||||
// Custom Draw method instead of inheriting from a generic Widget.
|
||||
func (self *TempWidget) Draw(buf *ui.Buffer) {
|
||||
self.Block.Draw(buf)
|
||||
func (temp *TempWidget) Draw(buf *ui.Buffer) {
|
||||
temp.Block.Draw(buf)
|
||||
|
||||
var keys []string
|
||||
for key := range self.Data {
|
||||
for key := range temp.Data {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for y, key := range keys {
|
||||
if y+1 > self.Inner.Dy() {
|
||||
if y+1 > temp.Inner.Dy() {
|
||||
break
|
||||
}
|
||||
|
||||
var fg ui.Color
|
||||
if self.Data[key] < self.TempThreshold {
|
||||
fg = self.TempLowColor
|
||||
if temp.Data[key] < temp.TempThreshold {
|
||||
fg = temp.TempLowColor
|
||||
} else {
|
||||
fg = self.TempHighColor
|
||||
fg = temp.TempHighColor
|
||||
}
|
||||
|
||||
s := ui.TrimString(key, (self.Inner.Dx() - 4))
|
||||
s := ui.TrimString(key, (temp.Inner.Dx() - 4))
|
||||
buf.SetString(s,
|
||||
ui.Theme.Default,
|
||||
image.Pt(self.Inner.Min.X, self.Inner.Min.Y+y),
|
||||
image.Pt(temp.Inner.Min.X, temp.Inner.Min.Y+y),
|
||||
)
|
||||
|
||||
if self.tempsMetric != nil {
|
||||
self.tempsMetric[key].Set(float64(self.Data[key]))
|
||||
if temp.tempsMetric != nil {
|
||||
temp.tempsMetric[key].Set(float64(temp.Data[key]))
|
||||
}
|
||||
temperature := fmt.Sprintf("%3d°%c", self.Data[key], self.TempScale)
|
||||
temperature := fmt.Sprintf("%3d°%c", temp.Data[key], temp.TempScale)
|
||||
|
||||
buf.SetString(
|
||||
temperature,
|
||||
ui.NewStyle(fg),
|
||||
image.Pt(self.Inner.Max.X-(len(temperature)-1), self.Inner.Min.Y+y),
|
||||
image.Pt(temp.Inner.Max.X-(len(temperature)-1), temp.Inner.Min.Y+y),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *TempWidget) update() {
|
||||
devices.UpdateTemps(self.Data)
|
||||
for name, val := range self.Data {
|
||||
if self.TempScale == Fahrenheit {
|
||||
self.Data[name] = utils.CelsiusToFahrenheit(val)
|
||||
func (temp *TempWidget) update() {
|
||||
devices.UpdateTemps(temp.Data)
|
||||
for name, val := range temp.Data {
|
||||
if temp.TempScale == Fahrenheit {
|
||||
temp.Data[name] = utils.CelsiusToFahrenheit(val)
|
||||
} else {
|
||||
self.Data[name] = val
|
||||
temp.Data[name] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user