mirror of
https://github.com/divan/expvarmon.git
synced 2025-04-25 13:48:54 +08:00
Code cleanups
This commit is contained in:
parent
0114f247c8
commit
41c8dfdc9a
16
data.go
16
data.go
@ -4,7 +4,7 @@ import "time"
|
||||
|
||||
// UIData represents data to be passed to UI.
|
||||
type UIData struct {
|
||||
Services Services
|
||||
Services []*Service
|
||||
Vars []VarName
|
||||
LastTimestamp time.Time
|
||||
}
|
||||
@ -15,17 +15,3 @@ func NewUIData(vars []VarName) *UIData {
|
||||
Vars: vars,
|
||||
}
|
||||
}
|
||||
|
||||
// FindService returns existing service by port.
|
||||
func (d *UIData) FindService(port string) *Service {
|
||||
if d.Services == nil {
|
||||
return nil
|
||||
}
|
||||
for _, service := range d.Services {
|
||||
if service.Port == port {
|
||||
return service
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
44
main.go
44
main.go
@ -3,17 +3,17 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/divan/termui"
|
||||
)
|
||||
|
||||
var (
|
||||
interval = flag.Duration("i", 5*time.Second, "Polling interval")
|
||||
portsArg = flag.String("ports", "40001,40002,40000,40004,1233,1234,1235", "Ports for accessing services expvars")
|
||||
defaultVars = flag.String("vars", "memstats.Alloc,memstats.Sys", "Default vars to monitor")
|
||||
extraVars = flag.String("extravars", "", "Comma-separated extra vars exported with expvars")
|
||||
dummy = flag.Bool("dummy", false, "Use dummy (console) output")
|
||||
interval = flag.Duration("i", 5*time.Second, "Polling interval")
|
||||
portsArg = flag.String("ports", "1234", "Ports for accessing services expvars")
|
||||
varsArg = flag.String("vars", "memstats.Alloc,memstats.Sys", "Default vars to monitor")
|
||||
dummy = flag.Bool("dummy", false, "Use dummy (console) output")
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -23,7 +23,7 @@ func main() {
|
||||
log.Fatal("cannot parse ports:", err)
|
||||
}
|
||||
|
||||
vars, err := ParseVars(*defaultVars, *extraVars)
|
||||
vars, err := ParseVars(*varsArg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -46,25 +46,11 @@ func main() {
|
||||
tick := time.NewTicker(*interval)
|
||||
evtCh := termui.EventCh()
|
||||
|
||||
update := func() {
|
||||
for _, port := range ports {
|
||||
service := data.FindService(port)
|
||||
if service == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
service.Update()
|
||||
}
|
||||
|
||||
data.LastTimestamp = time.Now()
|
||||
|
||||
ui.Update(*data)
|
||||
}
|
||||
update()
|
||||
UpdateAll(ui, data)
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
update()
|
||||
UpdateAll(ui, data)
|
||||
case e := <-evtCh:
|
||||
if e.Type == termui.EventKey && e.Ch == 'q' {
|
||||
return
|
||||
@ -76,3 +62,17 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateAll collects data from expvars and refreshes UI.
|
||||
func UpdateAll(ui UI, data *UIData) {
|
||||
var wg sync.WaitGroup
|
||||
for _, service := range data.Services {
|
||||
wg.Add(1)
|
||||
go service.Update(&wg)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
data.LastTimestamp = time.Now()
|
||||
|
||||
ui.Update(*data)
|
||||
}
|
||||
|
@ -5,11 +5,9 @@ import (
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Services is just a slice of Service.
|
||||
type Services []*Service
|
||||
|
||||
// Service represents constantly updating info about single service.
|
||||
type Service struct {
|
||||
Port string
|
||||
@ -36,7 +34,8 @@ func NewService(port string, vars []VarName) *Service {
|
||||
}
|
||||
|
||||
// Update updates Service info from Expvar variable.
|
||||
func (s *Service) Update() {
|
||||
func (s *Service) Update(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
expvar, err := FetchExpvar(s.Addr())
|
||||
s.Err = err
|
||||
|
||||
|
@ -74,7 +74,7 @@ func (t *TermUI) Init(data UIData) error {
|
||||
s := termui.NewSparklines(sparklines...)
|
||||
s.Height = 2*len(data.Services) + 2
|
||||
s.HasBorder = true
|
||||
s.Border.Label = fmt.Sprintf("Sparklines for %s", data.Vars[0])
|
||||
s.Border.Label = fmt.Sprintf("Monitoring %s", data.Vars[0])
|
||||
return s
|
||||
}()
|
||||
|
||||
|
19
utils.go
19
utils.go
@ -7,22 +7,15 @@ import (
|
||||
|
||||
// ParseVars returns parsed and validated slice of strings with
|
||||
// variables names that will be used for monitoring.
|
||||
func ParseVars(def, extra string) ([]VarName, error) {
|
||||
if def == "" && extra == "" {
|
||||
func ParseVars(vars string) ([]VarName, error) {
|
||||
if vars == "" {
|
||||
return nil, errors.New("no vars specified")
|
||||
}
|
||||
|
||||
fields := func(s string) []VarName {
|
||||
ss := strings.FieldsFunc(s, func(r rune) bool { return r == ',' })
|
||||
ret := []VarName{}
|
||||
for _, str := range ss {
|
||||
ret = append(ret, VarName(str))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
ss := strings.FieldsFunc(vars, func(r rune) bool { return r == ',' })
|
||||
var ret []VarName
|
||||
ret = append(ret, fields(def)...)
|
||||
ret = append(ret, fields(extra)...)
|
||||
for _, s := range ss {
|
||||
ret = append(ret, VarName(s))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
@ -3,10 +3,9 @@ package main
|
||||
import "testing"
|
||||
|
||||
func TestUtils(t *testing.T) {
|
||||
def := "memstats.Alloc,memstats.Sys"
|
||||
extra := ""
|
||||
str := "memstats.Alloc,memstats.Sys"
|
||||
|
||||
vars, err := ParseVars(def, extra)
|
||||
vars, err := ParseVars(str)
|
||||
if err != nil {
|
||||
t.Fatalf("Err not nil: %v", err)
|
||||
}
|
||||
@ -15,10 +14,9 @@ func TestUtils(t *testing.T) {
|
||||
t.Fatalf("vars should contain 2 elements, but has %d", len(vars))
|
||||
}
|
||||
|
||||
def = "memstats.Alloc,memstats.Sys"
|
||||
extra = "goroutines,counter.A"
|
||||
str = "memstats.Alloc,memstats.Sys,goroutines,Counter.A"
|
||||
|
||||
vars, err = ParseVars(def, extra)
|
||||
vars, err = ParseVars(str)
|
||||
if err != nil {
|
||||
t.Fatalf("Err not nil: %v", err)
|
||||
}
|
||||
|
@ -11,4 +11,9 @@ func TestVarName(t *testing.T) {
|
||||
if len(slice) != 2 || slice[0] != "memstats" || slice[1] != "Alloc" {
|
||||
t.Fatalf("ToSlice failed: %v", slice)
|
||||
}
|
||||
|
||||
short := v.Short()
|
||||
if short != "Alloc" {
|
||||
t.Fatalf("Expecting Short() to be 'Alloc', but got: %s", short)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user