1
0
mirror of https://github.com/divan/expvarmon.git synced 2025-04-25 13:48:54 +08:00
expvarmon/ui_single.go

169 lines
3.7 KiB
Go
Raw Permalink Normal View History

2015-05-02 21:17:51 +03:00
package main
import (
"fmt"
2015-05-03 15:59:37 +03:00
"time"
2015-05-02 21:17:51 +03:00
2019-01-19 11:40:36 +02:00
"github.com/gizak/termui"
2015-05-02 21:17:51 +03:00
)
// TermUISingle is a termUI implementation of UI interface.
type TermUISingle struct {
2019-01-19 11:40:36 +02:00
Title *termui.Paragraph
Status *termui.Paragraph
2015-05-02 21:17:51 +03:00
Sparklines map[VarName]*termui.Sparkline
Sparkline *termui.Sparklines
2019-01-19 11:40:36 +02:00
Pars []*termui.Paragraph
2015-05-02 21:17:51 +03:00
}
// Init creates widgets, sets sizes and labels.
func (t *TermUISingle) Init(data UIData) error {
err := termui.Init()
if err != nil {
return err
}
t.Sparklines = make(map[VarName]*termui.Sparkline)
2019-01-19 11:40:36 +02:00
t.Title = func() *termui.Paragraph {
p := termui.NewParagraph("")
2015-05-02 21:17:51 +03:00
p.Height = 3
p.TextFgColor = termui.ColorWhite
2019-01-19 11:40:36 +02:00
p.Border = true
p.BorderLabel = "Services Monitor"
p.BorderFg = termui.ColorCyan
2015-05-02 21:17:51 +03:00
return p
}()
2019-01-19 11:40:36 +02:00
t.Status = func() *termui.Paragraph {
p := termui.NewParagraph("")
2015-05-02 21:17:51 +03:00
p.Height = 3
p.TextFgColor = termui.ColorWhite
2019-01-19 11:40:36 +02:00
p.Border = true
p.BorderLabel = "Status"
p.BorderFg = termui.ColorCyan
2015-05-02 21:17:51 +03:00
return p
}()
2019-01-19 11:40:36 +02:00
t.Pars = make([]*termui.Paragraph, len(data.Vars))
2015-05-03 18:22:26 +03:00
for i, name := range data.Vars {
2019-01-19 11:40:36 +02:00
par := termui.NewParagraph("")
2015-05-03 18:22:26 +03:00
par.TextFgColor = colorByKind(name.Kind())
2019-01-19 11:40:36 +02:00
par.Border = true
par.BorderLabel = name.Short()
par.BorderLabelFg = termui.ColorGreen
2015-05-03 18:22:26 +03:00
par.Height = 3
t.Pars[i] = par
}
2015-05-02 22:29:02 +03:00
var sparklines []termui.Sparkline
2015-05-02 21:17:51 +03:00
for _, name := range data.Vars {
2015-05-02 22:29:02 +03:00
spl := termui.NewSparkline()
spl.Height = 1
spl.TitleColor = colorByKind(name.Kind())
spl.LineColor = colorByKind(name.Kind())
spl.Title = name.Long()
sparklines = append(sparklines, spl)
2015-05-02 21:17:51 +03:00
}
t.Sparkline = func() *termui.Sparklines {
2015-05-02 22:29:02 +03:00
s := termui.NewSparklines(sparklines...)
s.Height = 2*len(sparklines) + 2
2019-01-19 11:40:36 +02:00
s.Border = true
s.BorderLabel = fmt.Sprintf("Monitoring")
2015-05-02 21:17:51 +03:00
return s
}()
2015-05-03 18:03:49 +03:00
t.Relayout()
2015-05-02 21:17:51 +03:00
return nil
}
// Update updates UI widgets from UIData.
func (t *TermUISingle) Update(data UIData) {
// single mode assumes we have one service only to monitor
service := data.Services[0]
2015-05-02 22:54:00 +03:00
t.Title.Text = fmt.Sprintf("monitoring %s every %v, press q to quit", service.Name, *interval)
2015-05-03 15:59:37 +03:00
t.Status.Text = fmt.Sprintf("Last update: %v", data.LastTimestamp.Format(time.Stamp))
2015-05-02 21:17:51 +03:00
2015-05-03 18:22:26 +03:00
// Pars
for i, name := range data.Vars {
t.Pars[i].Text = service.Value(name)
}
2015-05-02 21:17:51 +03:00
// Sparklines
for i, name := range data.Vars {
spl := &t.Sparkline.Lines[i]
2015-05-02 22:29:02 +03:00
2015-05-02 22:39:39 +03:00
max := formatMax(service.Max(name))
spl.Title = fmt.Sprintf("%s: %v%s", name.Long(), service.Value(name), max)
2015-05-02 21:17:51 +03:00
spl.TitleColor = colorByKind(name.Kind())
spl.LineColor = colorByKind(name.Kind())
2015-05-02 22:48:27 +03:00
if name.Kind() == KindString {
continue
}
2015-05-02 21:17:51 +03:00
spl.Data = service.Values(name)
}
2015-05-03 18:03:49 +03:00
t.Relayout()
var widgets []termui.Bufferer
widgets = append(widgets, t.Title, t.Status, t.Sparkline)
2015-05-03 18:22:26 +03:00
for _, par := range t.Pars {
widgets = append(widgets, par)
}
2015-05-03 18:03:49 +03:00
termui.Render(widgets...)
2015-05-02 21:17:51 +03:00
}
// Close shuts down UI module.
func (t *TermUISingle) Close() {
termui.Close()
}
2015-05-02 22:39:39 +03:00
2015-05-03 18:03:49 +03:00
// Relayout recalculates widgets sizes and coords.
func (t *TermUISingle) Relayout() {
tw, th := termui.TermWidth(), termui.TermHeight()
h := th
// First row: Title and Status pars
firstRowH := 3
t.Title.Height = firstRowH
t.Title.Width = tw / 2
if tw%2 == 1 {
2015-05-03 21:59:45 +03:00
t.Title.Width++
2015-05-03 18:03:49 +03:00
}
t.Status.Height = firstRowH
t.Status.Width = tw / 2
t.Status.X = t.Title.X + t.Title.Width
h -= firstRowH
2015-05-03 18:22:26 +03:00
// Second row: lists
secondRowH := 3
num := len(t.Pars)
parW := tw / num
for i, par := range t.Pars {
par.Y = th - h
par.Width = parW
par.Height = secondRowH
par.X = i * parW
}
if num*parW < tw {
t.Pars[num-1].Width = tw - ((num - 1) * parW)
}
h -= secondRowH
// Third row: Sparklines
2015-05-03 18:03:49 +03:00
t.Sparkline.Width = tw
t.Sparkline.Height = h
t.Sparkline.Y = th - h
}
2015-05-02 22:39:39 +03:00
func formatMax(max interface{}) string {
var str string
if max != nil {
str = fmt.Sprintf(" (max: %v)", max)
}
return str
}