Extensions.
This commit is contained in:
parent
7a89225d72
commit
231b0d03fe
@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"plugin"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
@ -33,6 +34,7 @@ const (
|
||||
defaultUI = "cpu\ndisk/1 2:mem/2\ntemp\nnet procs"
|
||||
minimalUI = "cpu\nmem procs"
|
||||
batteryUI = "cpu/2 batt/1\ndisk/1 2:mem/2\ntemp\nnet procs"
|
||||
procsUI = "cpu 4:procs\ndisk\nmem\nnet"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -65,12 +67,16 @@ Options:
|
||||
-b, --battery Show battery level widget ('minimal' turns off). (DEPRECATED, use -l battery)
|
||||
-B, --bandwidth=bits Specify the number of bits per seconds.
|
||||
-l, --layout=NAME Name of layout spec file for the UI. Looks first in $XDG_CONFIG_HOME/gotop, then as a path. Use "-" to pipe.
|
||||
-i, --interface=NAME Select network interface [default: all].
|
||||
-i, --interface=NAME Select network interface [default: all]. Several interfaces can be defined using comma separated values. Interfaces can also be ignored using !
|
||||
-x, --export=PORT Enable metrics for export on the specified port.
|
||||
-X, --extensions=NAMES Enables the listed extensions. This is a comma-separated list without the .so suffix. The current and config directories will be searched.
|
||||
|
||||
Several interfaces can be defined using comma separated values.
|
||||
|
||||
Interfaces can also be ignored using !
|
||||
Built-in layouts:
|
||||
default
|
||||
minimal
|
||||
battery
|
||||
kitchensink
|
||||
|
||||
Colorschemes:
|
||||
default
|
||||
@ -142,6 +148,10 @@ Colorschemes:
|
||||
if val, _ := args["--interface"]; val != nil {
|
||||
conf.NetInterface, _ = args["--interface"].(string)
|
||||
}
|
||||
if val, _ := args["--extensions"]; val != nil {
|
||||
exs, _ := args["--extensions"].(string)
|
||||
conf.Extensions = strings.Split(exs, ",")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -386,6 +396,8 @@ func main() {
|
||||
bar = w.NewStatusBar()
|
||||
}
|
||||
|
||||
loadExtensions(conf)
|
||||
|
||||
lstream := getLayout(conf)
|
||||
ly := layout.ParseLayout(lstream)
|
||||
grid, err := layout.Layout(ly, conf)
|
||||
@ -426,6 +438,8 @@ func getLayout(conf gotop.Config) io.Reader {
|
||||
return strings.NewReader(minimalUI)
|
||||
case "battery":
|
||||
return strings.NewReader(batteryUI)
|
||||
case "procs":
|
||||
return strings.NewReader(procsUI)
|
||||
default:
|
||||
fp := filepath.Join(conf.ConfigDir, conf.Layout)
|
||||
fin, err := os.Open(fp)
|
||||
@ -438,3 +452,47 @@ func getLayout(conf gotop.Config) io.Reader {
|
||||
return fin
|
||||
}
|
||||
}
|
||||
|
||||
func loadExtensions(conf gotop.Config) {
|
||||
var hasError bool
|
||||
for _, ex := range conf.Extensions {
|
||||
exf := ex + ".so"
|
||||
fn := exf
|
||||
_, err := os.Stat(fn)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
log.Printf("no plugin %s found in current directory", fn)
|
||||
fn = filepath.Join(conf.ConfigDir, exf)
|
||||
_, err = os.Stat(fn)
|
||||
if err != nil || os.IsNotExist(err) {
|
||||
hasError = true
|
||||
log.Printf("no plugin %s found in config directory", fn)
|
||||
continue
|
||||
}
|
||||
}
|
||||
p, err := plugin.Open(fn)
|
||||
if err != nil {
|
||||
hasError = true
|
||||
log.Printf(err.Error())
|
||||
continue
|
||||
}
|
||||
init, err := p.Lookup("Init")
|
||||
if err != nil {
|
||||
hasError = true
|
||||
log.Printf(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
initFunc, ok := init.(func())
|
||||
if !ok {
|
||||
hasError = true
|
||||
log.Printf(err.Error())
|
||||
continue
|
||||
}
|
||||
initFunc()
|
||||
}
|
||||
if hasError {
|
||||
ui.Close()
|
||||
fmt.Printf("Error initializing requested plugins; check the log file %s\n", filepath.Join(conf.ConfigDir, conf.LogFile))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,7 @@ func init() {
|
||||
|
||||
BattLines: []int{4, 3, 2, 1, 5, 6, 7, 8},
|
||||
|
||||
MainMem: 5,
|
||||
SwapMem: 11,
|
||||
MemLines: []int{5, 11, 4, 3, 2, 1, 6, 7, 8},
|
||||
|
||||
ProcCursor: 4,
|
||||
|
||||
|
@ -11,8 +11,7 @@
|
||||
|
||||
"BattLines": [4, 3, 2, 1, 5, 6, 7, 8],
|
||||
|
||||
"MainMem": 5,
|
||||
"SwapMem": 11,
|
||||
"MemLines": [5, 11, 4, 3, 2, 1, 6, 7, 8],
|
||||
|
||||
"ProcCursor": 4,
|
||||
|
||||
|
@ -12,8 +12,7 @@ func init() {
|
||||
|
||||
BattLines: []int{4, 3, 2, 1, 5, 6, 7, 8},
|
||||
|
||||
MainMem: 5,
|
||||
SwapMem: 3,
|
||||
MemLines: []int{5, 3, 4, 2, 1, 6, 7, 8, 11},
|
||||
|
||||
ProcCursor: 33,
|
||||
|
||||
|
@ -12,8 +12,7 @@ func init() {
|
||||
|
||||
BattLines: []int{81, 70, 208, 197, 249, 141, 221, 186},
|
||||
|
||||
MainMem: 208,
|
||||
SwapMem: 186,
|
||||
MemLines: []int{208, 186, 81, 70, 208, 197, 249, 141, 221, 186},
|
||||
|
||||
ProcCursor: 197,
|
||||
|
||||
|
@ -25,8 +25,7 @@ func init() {
|
||||
|
||||
BattLines: []int{4, 3, 2, 1, 5, 6, 7, 8},
|
||||
|
||||
MainMem: 172, // Orange
|
||||
SwapMem: 221, // yellow
|
||||
MemLines: []int{172, 221, 4, 3, 2, 1, 5, 6, 7, 8},
|
||||
|
||||
ProcCursor: 31, // blue (nord9)
|
||||
|
||||
|
@ -15,8 +15,7 @@ func init() {
|
||||
|
||||
BattLines: []int{61, 33, 37, 64, 125, 160, 166, 136},
|
||||
|
||||
MainMem: 125,
|
||||
SwapMem: 166,
|
||||
MemLines: []int{125, 166, 61, 33, 37, 64, 125, 160, 166, 136},
|
||||
|
||||
ProcCursor: 136,
|
||||
|
||||
|
@ -14,8 +14,7 @@ func init() {
|
||||
|
||||
BattLines: []int{13, 4, 6, 2, 5, 1, 9, 3},
|
||||
|
||||
MainMem: 5,
|
||||
SwapMem: 9,
|
||||
MemLines: []int{5, 9, 13, 4, 6, 2, 1, 3},
|
||||
|
||||
ProcCursor: 4,
|
||||
|
||||
|
@ -14,8 +14,7 @@ func init() {
|
||||
|
||||
BattLines: []int{13, 4, 6, 2, 5, 1, 9, 3},
|
||||
|
||||
MainMem: 5,
|
||||
SwapMem: 9,
|
||||
MemLines: []int{5, 9, 13, 4, 6, 2, 1, 3},
|
||||
|
||||
ProcCursor: 4,
|
||||
|
||||
|
@ -32,8 +32,7 @@ type Colorscheme struct {
|
||||
|
||||
BattLines []int
|
||||
|
||||
MainMem int
|
||||
SwapMem int
|
||||
MemLines []int
|
||||
|
||||
ProcCursor int
|
||||
|
||||
|
@ -12,8 +12,7 @@ func init() {
|
||||
|
||||
BattLines: []int{212, 218, 123, 159, 229, 158, 183, 146},
|
||||
|
||||
MainMem: 201,
|
||||
SwapMem: 97,
|
||||
MemLines: []int{201, 97, 212, 218, 123, 159, 229, 158, 183, 146},
|
||||
|
||||
ProcCursor: 159,
|
||||
|
||||
|
@ -31,6 +31,7 @@ type Config struct {
|
||||
Layout string
|
||||
MaxLogSize int64
|
||||
ExportPort string
|
||||
Extensions []string
|
||||
}
|
||||
|
||||
func Parse(in io.Reader, conf *Config) error {
|
||||
@ -112,6 +113,8 @@ func Parse(in io.Reader, conf *Config) error {
|
||||
conf.MaxLogSize = int64(iv)
|
||||
case "export":
|
||||
conf.ExportPort = kv[1]
|
||||
case "extensions":
|
||||
conf.Extensions = strings.Split(kv[1], ",")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var cpuFuncs []func(map[string]float64, time.Duration, bool) map[string]error
|
||||
var cpuFuncs []func(map[string]int, time.Duration, bool) map[string]error
|
||||
|
||||
// RegisterCPU adds a new CPU device to the CPU widget. labels returns the
|
||||
// names of the devices; they should be as short as possible, and the indexes
|
||||
@ -16,13 +16,13 @@ var cpuFuncs []func(map[string]float64, time.Duration, bool) map[string]error
|
||||
//
|
||||
// labels may be called once and the value cached. This means the number of
|
||||
// cores should not change dynamically.
|
||||
func RegisterCPU(f func(map[string]float64, time.Duration, bool) map[string]error) {
|
||||
func RegisterCPU(f func(map[string]int, time.Duration, bool) map[string]error) {
|
||||
cpuFuncs = append(cpuFuncs, f)
|
||||
}
|
||||
|
||||
// CPUPercent calculates the percentage of cpu used either per CPU or combined.
|
||||
// Returns one value per cpu, or a single value if percpu is set to false.
|
||||
func UpdateCPU(cpus map[string]float64, interval time.Duration, logical bool) {
|
||||
func UpdateCPU(cpus map[string]int, interval time.Duration, logical bool) {
|
||||
for _, f := range cpuFuncs {
|
||||
errs := f(cpus, interval, logical)
|
||||
if errs != nil {
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
f := func(cpus map[string]float64, iv time.Duration, l bool) map[string]error {
|
||||
f := func(cpus map[string]int, iv time.Duration, l bool) map[string]error {
|
||||
cpuCount, err := psCpu.Counts(l)
|
||||
if err != nil {
|
||||
return nil
|
||||
@ -23,7 +23,7 @@ func init() {
|
||||
}
|
||||
for i := 0; i < len(vals); i++ {
|
||||
key := fmt.Sprintf(formatString, i)
|
||||
cpus[key] = vals[i]
|
||||
cpus[key] = int(vals[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -168,8 +168,15 @@ func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
|
||||
w = dw
|
||||
case "mem":
|
||||
m := widgets.NewMemWidget(c.UpdateInterval, c.GraphHorizontalScale)
|
||||
m.LineColors["Main"] = ui.Color(c.Colorscheme.MainMem)
|
||||
m.LineColors["Swap"] = ui.Color(c.Colorscheme.SwapMem)
|
||||
var i int
|
||||
for key, _ := range m.Data {
|
||||
if i >= len(c.Colorscheme.MemLines) {
|
||||
i = 0
|
||||
}
|
||||
color := c.Colorscheme.MemLines[i]
|
||||
m.LineColors[key] = ui.Color(color)
|
||||
i++
|
||||
}
|
||||
w = m
|
||||
case "temp":
|
||||
t := widgets.NewTempWidget(c.TempScale)
|
||||
|
@ -48,10 +48,10 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage
|
||||
}
|
||||
|
||||
if self.ShowPerCpuLoad {
|
||||
cpus := make(map[string]float64)
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad)
|
||||
for k, v := range cpus {
|
||||
self.Data[k] = []float64{v}
|
||||
self.Data[k] = []float64{float64(v)}
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ func (self *CpuWidget) EnableMetric() {
|
||||
Name: "avg",
|
||||
})
|
||||
} else {
|
||||
cpus := make(map[string]float64)
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad)
|
||||
self.metric = make(map[string]prometheus.Gauge)
|
||||
for key, perc := range cpus {
|
||||
@ -83,7 +83,7 @@ func (self *CpuWidget) EnableMetric() {
|
||||
Subsystem: "cpu",
|
||||
Name: key,
|
||||
})
|
||||
gauge.Set(perc)
|
||||
gauge.Set(float64(perc))
|
||||
prometheus.MustRegister(gauge)
|
||||
self.metric[key] = gauge
|
||||
}
|
||||
@ -97,7 +97,7 @@ func (b *CpuWidget) Scale(i int) {
|
||||
func (self *CpuWidget) update() {
|
||||
if self.ShowAverageLoad {
|
||||
go func() {
|
||||
cpus := make(map[string]float64)
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, false)
|
||||
self.Lock()
|
||||
defer self.Unlock()
|
||||
@ -105,7 +105,7 @@ func (self *CpuWidget) update() {
|
||||
defer self.updateLock.Unlock()
|
||||
var val float64
|
||||
for _, v := range cpus {
|
||||
val = v
|
||||
val = float64(v)
|
||||
break
|
||||
}
|
||||
self.Data["AVRG"] = append(self.Data["AVRG"], val)
|
||||
@ -118,20 +118,20 @@ func (self *CpuWidget) update() {
|
||||
|
||||
if self.ShowPerCpuLoad {
|
||||
go func() {
|
||||
cpus := make(map[string]float64)
|
||||
cpus := make(map[string]int)
|
||||
devices.UpdateCPU(cpus, self.updateInterval, true)
|
||||
self.Lock()
|
||||
defer self.Unlock()
|
||||
self.updateLock.Lock()
|
||||
defer self.updateLock.Unlock()
|
||||
for key, percent := range cpus {
|
||||
self.Data[key] = append(self.Data[key], percent)
|
||||
self.Labels[key] = fmt.Sprintf("%3.0f%%", percent)
|
||||
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 {
|
||||
log.Printf("no metrics for %s", key)
|
||||
} else {
|
||||
self.metric[key].Set(percent)
|
||||
self.metric[key].Set(float64(percent))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package widgets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@ -27,7 +28,8 @@ func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget
|
||||
mems := make(map[string]devices.MemoryInfo)
|
||||
devices.UpdateMem(mems)
|
||||
for name, mem := range mems {
|
||||
self.Data[name] = []float64{mem.UsedPercent}
|
||||
log.Printf("setting %s to %v", name, mem)
|
||||
self.Data[name] = []float64{0}
|
||||
self.renderMemInfo(name, mem)
|
||||
}
|
||||
|
||||
@ -36,6 +38,7 @@ func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget
|
||||
self.Lock()
|
||||
devices.UpdateMem(mems)
|
||||
for label, mi := range mems {
|
||||
log.Printf(" updating %s to %v", label, mi)
|
||||
self.renderMemInfo(label, mi)
|
||||
if self.metrics != nil && self.metrics[label] != nil {
|
||||
self.metrics[label].Set(mi.UsedPercent)
|
||||
|
Loading…
x
Reference in New Issue
Block a user