mirror of https://github.com/divan/expvarmon.git
Moved sparklines data (stacks) to UI data structure
This commit is contained in:
parent
93da8b7853
commit
555bff1b9d
12
data.go
12
data.go
|
@ -7,11 +7,21 @@ type UIData struct {
|
|||
Services []*Service
|
||||
Vars []VarName
|
||||
LastTimestamp time.Time
|
||||
Stacks map[VarName]*Stack
|
||||
Stats map[VarName]*Stat
|
||||
}
|
||||
|
||||
// NewUIData inits and return new data object.
|
||||
func NewUIData(vars []VarName) *UIData {
|
||||
stacks := make(map[VarName]*Stack)
|
||||
stats := make(map[VarName]*Stat)
|
||||
for _, v := range vars {
|
||||
stacks[v] = NewStack()
|
||||
stats[v] = NewStat()
|
||||
}
|
||||
return &UIData{
|
||||
Vars: vars,
|
||||
Vars: vars,
|
||||
Stacks: stacks,
|
||||
Stats: stats,
|
||||
}
|
||||
}
|
||||
|
|
79
stack.go
79
stack.go
|
@ -8,9 +8,8 @@ const DefaultSize = 1200
|
|||
|
||||
// Stack is a limited FIFO for holding sparkline values.
|
||||
type Stack struct {
|
||||
Values []Var
|
||||
Values []int
|
||||
Len int
|
||||
Max Var
|
||||
}
|
||||
|
||||
// NewStack inits new Stack with default size limit.
|
||||
|
@ -21,88 +20,26 @@ func NewStack() *Stack {
|
|||
// NewStackWithSize inits new Stack with size limit.
|
||||
func NewStackWithSize(size int) *Stack {
|
||||
return &Stack{
|
||||
Values: make([]Var, size),
|
||||
Values: make([]int, size),
|
||||
Len: size,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: FIXME: review or remove this code
|
||||
// Push inserts data to stack, preserving constant length.
|
||||
func (s *Stack) Push(val Var) {
|
||||
func (s *Stack) Push(v IntVar) {
|
||||
val := v.Value()
|
||||
s.Values = append(s.Values, val)
|
||||
if len(s.Values) > s.Len {
|
||||
// TODO: check if underlying array is growing constantly
|
||||
s.Values = s.Values[1:]
|
||||
}
|
||||
|
||||
if s.Max == nil {
|
||||
s.Max = val
|
||||
return
|
||||
}
|
||||
|
||||
switch val.(type) {
|
||||
case int64:
|
||||
switch s.Max.(type) {
|
||||
case int64:
|
||||
if val.(int64) > s.Max.(int64) {
|
||||
s.Max = val
|
||||
}
|
||||
case float64:
|
||||
if float64(val.(int64)) > s.Max.(float64) {
|
||||
s.Max = val
|
||||
}
|
||||
}
|
||||
case float64:
|
||||
switch s.Max.(type) {
|
||||
case int64:
|
||||
if val.(float64) > float64(s.Max.(int64)) {
|
||||
s.Max = val
|
||||
}
|
||||
case float64:
|
||||
if val.(float64) > s.Max.(float64) {
|
||||
s.Max = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Front returns front value.
|
||||
func (s *Stack) Front() Var {
|
||||
if len(s.Values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return s.Values[len(s.Values)-1]
|
||||
}
|
||||
|
||||
// IntValues returns stack values explicitly casted to int.
|
||||
//
|
||||
// Main case is to use with termui.Sparklines.
|
||||
func (s *Stack) IntValues() []int {
|
||||
ret := make([]int, s.Len)
|
||||
for i, v := range s.Values {
|
||||
n, ok := v.(int64)
|
||||
if ok {
|
||||
ret[i] = int(n)
|
||||
continue
|
||||
}
|
||||
|
||||
f, ok := v.(float64)
|
||||
if ok {
|
||||
// 12.34 (float) -> 1234 (int)
|
||||
ret[i] = int(f * 100)
|
||||
continue
|
||||
}
|
||||
|
||||
b, ok := v.(bool)
|
||||
if ok {
|
||||
// false => 0, true = 1
|
||||
if b {
|
||||
ret[i] = 1
|
||||
} else {
|
||||
ret[i] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
return s.Values
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: implement trim and resize
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
// Stat holds basic statistics data for
|
||||
// integer data used for sparklines.
|
||||
type Stat struct {
|
||||
max IntVar
|
||||
// TODO: implement running median
|
||||
}
|
||||
|
||||
// NewStat inits new Stat object.
|
||||
func NewStat() *Stat {
|
||||
return &Stat{
|
||||
max: &Number{},
|
||||
}
|
||||
}
|
||||
|
||||
// Update updates stats on each push.
|
||||
func (s *Stat) Update(v IntVar) {
|
||||
if v.Value() > s.max.Value() {
|
||||
s.max = v
|
||||
}
|
||||
}
|
||||
|
||||
// Max returns maximum recorded value.
|
||||
func (s *Stat) Max() IntVar {
|
||||
return s.max
|
||||
}
|
30
ui_multi.go
30
ui_multi.go
|
@ -68,7 +68,7 @@ func (t *TermUI) Init(data UIData) error {
|
|||
var sparklines []termui.Sparkline
|
||||
for _, service := range data.Services {
|
||||
spl := termui.NewSparkline()
|
||||
spl.Height = 1
|
||||
spl.Height = 1 // TODO: set height to th/len(services)
|
||||
spl.LineColor = termui.ColorGreen
|
||||
spl.Title = service.Name
|
||||
sparklines = append(sparklines, spl)
|
||||
|
@ -113,14 +113,28 @@ func (t *TermUI) Update(data UIData) {
|
|||
|
||||
// Sparklines
|
||||
for i, service := range data.Services {
|
||||
max := "MAX" // TODO: FIXME: formatMax(service.Max(data.Vars[0]))
|
||||
t.Sparkline1.Lines[i].Title = fmt.Sprintf("%s%s", service.Name, max)
|
||||
t.Sparkline1.Lines[i].Data = []int{} // TODO: service.Values(data.Vars[0])
|
||||
name := data.Vars[0]
|
||||
v, ok := service.Vars[name].(IntVar)
|
||||
if ok {
|
||||
data.Stacks[name].Push(v)
|
||||
data.Stats[name].Update(v)
|
||||
max := data.Stats[name].Max().String()
|
||||
t.Sparkline1.Lines[i].Title = fmt.Sprintf("%s (max: %s)", service.Name, max)
|
||||
t.Sparkline1.Lines[i].Data = data.Stacks[name].IntValues()
|
||||
}
|
||||
|
||||
if len(data.Vars) > 1 {
|
||||
max = "MAX" // TODO: FIXME: formatMax(service.Max(data.Vars[1]))
|
||||
t.Sparkline2.Lines[i].Title = fmt.Sprintf("%s%s", service.Name, max)
|
||||
t.Sparkline2.Lines[i].Data = []int{} // TODO: service.Values(data.Vars[1])
|
||||
if len(data.Vars) == 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
name = data.Vars[1]
|
||||
v, ok = service.Vars[name].(IntVar)
|
||||
if ok {
|
||||
data.Stacks[name].Push(v)
|
||||
data.Stats[name].Update(v)
|
||||
max := data.Stats[name].Max().String()
|
||||
t.Sparkline2.Lines[i].Title = fmt.Sprintf("%s (max: %s)", service.Name, max)
|
||||
t.Sparkline2.Lines[i].Data = data.Stacks[name].IntValues()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
ui_single.go
16
ui_single.go
|
@ -92,17 +92,21 @@ func (t *TermUISingle) Update(data UIData) {
|
|||
|
||||
// Sparklines
|
||||
for i, name := range data.Vars {
|
||||
v, ok := service.Vars[name].(IntVar)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
data.Stacks[name].Push(v)
|
||||
data.Stats[name].Update(v)
|
||||
|
||||
spl := &t.Sparkline.Lines[i]
|
||||
|
||||
max := "MAX" // FIXME: formatMax(service.Max(name))
|
||||
spl.Title = fmt.Sprintf("%s: %v%s", name.Long(), service.Value(name), max)
|
||||
max := data.Stats[name].Max().String()
|
||||
spl.Title = fmt.Sprintf("%s: %v (max: %v)", name.Long(), service.Value(name), max)
|
||||
spl.TitleColor = colorByKind(name.Kind())
|
||||
spl.LineColor = colorByKind(name.Kind())
|
||||
|
||||
if name.Kind() == KindString {
|
||||
continue
|
||||
}
|
||||
spl.Data = []int{} // FIXME: service.Values(name)
|
||||
spl.Data = data.Stacks[name].IntValues()
|
||||
}
|
||||
|
||||
t.Relayout()
|
||||
|
|
24
var.go
24
var.go
|
@ -27,6 +27,13 @@ type Var interface {
|
|||
Set(*jason.Value)
|
||||
}
|
||||
|
||||
// IntVar represents variable which value can be represented as integer,
|
||||
// and suitable for displaying with sparklines.
|
||||
type IntVar interface {
|
||||
Var
|
||||
Value() int
|
||||
}
|
||||
|
||||
type Number struct {
|
||||
// TODO: add mutex here or level above, in service?
|
||||
val float64
|
||||
|
@ -46,6 +53,11 @@ func (v *Number) Set(j *jason.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
// Value implements IntVar for Number type.
|
||||
func (v *Number) Value() int {
|
||||
return int(v.val)
|
||||
}
|
||||
|
||||
type Memory struct {
|
||||
bytes int64
|
||||
}
|
||||
|
@ -62,6 +74,12 @@ func (v *Memory) Set(j *jason.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
// Value implements IntVar for Memory type.
|
||||
func (v *Memory) Value() int {
|
||||
// TODO: check for possible overflows
|
||||
return int(v.bytes)
|
||||
}
|
||||
|
||||
type Duration struct {
|
||||
dur time.Duration
|
||||
}
|
||||
|
@ -81,6 +99,12 @@ func (v *Duration) Set(j *jason.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
// Value implements IntVar for Duration type.
|
||||
func (v *Duration) Value() int {
|
||||
// TODO: check for possible overflows
|
||||
return int(v.dur)
|
||||
}
|
||||
|
||||
type String struct {
|
||||
str string
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue