Merge branch 'gauge' into v3.4.x

This commit is contained in:
Sean E. Russell 2020-02-19 10:40:45 -06:00
commit 66ad0f8785
7 changed files with 116 additions and 3 deletions

View File

@ -15,9 +15,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [3.4.x] -
- Adds metrics. If run with the `--export :2112` flag (`:2112` is a port),
- Added: metrics. If run with the `--export :2112` flag (`:2112` is a port),
metrics are exposed as Prometheus metrics on that port and can be HTTP
GET-ted.
- Added: a battery gauge as a `power` widget; battery as a bar rather than
a histogram.
## [3.3.1] - 2020-02-18

View File

@ -94,7 +94,7 @@ and these are separated by spaces.
1. Each line is a row
2. Empty lines are skipped
3. Spaces are compressed (so you can do limited visual formatting)
4. Legal widget names are: cpu, disk, mem, temp, batt, net, procs
4. Legal widget names are: cpu, disk, mem, temp, batt, net, procs, power
5. Widget names are not case sensitive
4. The simplest row is a single widget, by name, e.g.
```

View File

@ -27,7 +27,7 @@ import (
const (
appName = "gotop"
version = "3.3.1"
version = "3.4.0"
graphHorizontalScaleDelta = 3
defaultUI = "cpu\ndisk/1 2:mem/2\ntemp\nnet procs"
@ -43,6 +43,7 @@ var (
stderrLogger = log.New(os.Stderr, "", 0)
)
// TODO: Add tab completion for Linux https://gist.github.com/icholy/5314423
func parseArgs(conf *gotop.Config) error {
usage := `
Usage: gotop [options]
@ -346,6 +347,7 @@ func makeConfig() gotop.Config {
return conf
}
// TODO: mpd visualizer widget
func main() {
// Set up default config
conf := makeConfig()

View File

@ -59,6 +59,7 @@ func Layout(wl layout, c gotop.Config) (*MyGrid, error) {
// rows as the largest row span object in the row, and produce an uber-row
// containing all that stuff. It returns a slice without the consumed elements.
func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) (ui.GridItem, [][]widgetRule) {
// FIXME: 3\:A 2\:B\nC should stop consuming rows when all columns are full
// Recursive function #3. See the comment in deepFindProc.
if len(rowDefs) < 1 {
return ui.GridItem{}, [][]widgetRule{}
@ -190,6 +191,10 @@ func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
i++
}
w = b
case "power":
b := widgets.NewBatteryGauge()
b.BarColor = ui.Color(c.Colorscheme.ProcCursor)
w = b
default:
log.Printf("Invalid widget name %s. Must be one of %v", widRule.Widget, widgetNames)
return ui.NewBlock()

5
layouts/kitchensink Normal file
View File

@ -0,0 +1,5 @@
cpu/2 mem/1
3:temp/1 2:disk/2
power
power
net procs

22
termui/gauge.go Normal file
View File

@ -0,0 +1,22 @@
package termui
import (
. "github.com/gizak/termui/v3"
gizak "github.com/gizak/termui/v3/widgets"
)
// LineGraph implements a line graph of data points.
type Gauge struct {
*gizak.Gauge
}
func NewGauge() *Gauge {
return &Gauge{
Gauge: gizak.NewGauge(),
}
}
func (self *Gauge) Draw(buf *Buffer) {
self.Gauge.Draw(buf)
self.Gauge.SetRect(self.Min.X, self.Min.Y, self.Inner.Dx(), self.Inner.Dy())
}

77
widgets/batterygauge.go Normal file
View File

@ -0,0 +1,77 @@
package widgets
import (
"fmt"
"log"
//"math"
//"strconv"
"time"
"github.com/distatus/battery"
"github.com/prometheus/client_golang/prometheus"
. "github.com/xxxserxxx/gotop/termui"
)
type BatteryGauge struct {
*Gauge
metric prometheus.Gauge
}
func NewBatteryGauge() *BatteryGauge {
self := &BatteryGauge{Gauge: NewGauge()}
self.Title = " Power Level "
self.update()
go func() {
for range time.NewTicker(time.Second).C {
self.Lock()
self.update()
self.Unlock()
}
}()
return self
}
func (b *BatteryGauge) EnableMetric() {
bats, err := battery.GetAll()
if err != nil {
log.Printf("error setting up metrics: %v", err)
return
}
mx := 0.0
cu := 0.0
for _, bat := range bats {
mx += bat.Full
cu += bat.Current
gauge := prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "gotop",
Subsystem: "battery",
Name: "total",
})
gauge.Set(cu / mx)
b.metric = gauge
prometheus.MustRegister(gauge)
}
}
func (self *BatteryGauge) update() {
bats, err := battery.GetAll()
if err != nil {
log.Printf("error setting up metrics: %v", err)
return
}
mx := 0.0
cu := 0.0
for _, bat := range bats {
mx += bat.Full
cu += bat.Current
}
self.Percent = int((cu / mx) * 100.0)
self.Label = fmt.Sprintf("%d%%", self.Percent)
if self.metric != nil {
self.metric.Set(cu / mx)
}
}