mirror of https://github.com/divan/expvarmon.git
Add BarChart for GC pauses
This commit is contained in:
parent
86e5c63eaf
commit
794515330a
13
data.go
13
data.go
|
@ -9,6 +9,7 @@ type UIData struct {
|
|||
LastTimestamp time.Time
|
||||
|
||||
SparklineData []*SparklineData
|
||||
HasBarchart bool
|
||||
}
|
||||
|
||||
// SparklineData holds additional data needed for sparklines.
|
||||
|
@ -37,9 +38,21 @@ func NewUIData(vars []VarName, services []*Service) *UIData {
|
|||
for i, _ := range services {
|
||||
sp[i] = NewSparklineData(vars)
|
||||
}
|
||||
|
||||
hasGCPauses := func(vars []VarName) bool {
|
||||
for _, v := range vars {
|
||||
if v.Kind() == KindGCPauses {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return &UIData{
|
||||
Services: services,
|
||||
Vars: vars,
|
||||
SparklineData: sp,
|
||||
|
||||
HasBarchart: hasGCPauses(vars),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,6 @@ func (s *Service) Update(wg *sync.WaitGroup) {
|
|||
value, err := expvar.GetValue(name.ToSlice()...)
|
||||
if err != nil {
|
||||
v.Set(nil)
|
||||
continue
|
||||
}
|
||||
v.Set(value)
|
||||
}
|
||||
|
|
55
ui_single.go
55
ui_single.go
|
@ -2,8 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/divan/gcpauses"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"gopkg.in/gizak/termui.v1"
|
||||
|
@ -113,7 +111,7 @@ func (t *TermUISingle) Update(data UIData) {
|
|||
|
||||
spl := &t.Sparkline.Lines[i]
|
||||
|
||||
max := data.SparklineData[i].Stats[name].Max().String()
|
||||
max := data.SparklineData[0].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())
|
||||
|
@ -122,25 +120,36 @@ func (t *TermUISingle) Update(data UIData) {
|
|||
}
|
||||
|
||||
// BarChart
|
||||
var m runtime.MemStats
|
||||
runtime.ReadMemStats(&m)
|
||||
p := gcpauses.NewGCPauses(&m)
|
||||
values, counts := p.Histogram(25)
|
||||
vals := make([]int, 0, len(counts))
|
||||
labels := make([]string, 0, len(counts))
|
||||
for i := 0; i < len(counts); i++ {
|
||||
vals = append(vals, int(counts[i]))
|
||||
d := time.Duration(values[i])
|
||||
labels = append(labels, d.String())
|
||||
if data.HasBarchart {
|
||||
var gcpauses *GCPauses
|
||||
for _, v := range service.Vars {
|
||||
if v.Kind() == KindGCPauses {
|
||||
gcpauses = v.(*GCPauses)
|
||||
break
|
||||
}
|
||||
}
|
||||
hist := gcpauses.Histogram(20)
|
||||
values, counts := hist.BarchartData()
|
||||
vals := make([]int, 0, len(counts))
|
||||
labels := make([]string, 0, len(counts))
|
||||
for i := 0; i < len(counts); i++ {
|
||||
vals = append(vals, int(counts[i]))
|
||||
d := roundDuration(time.Duration(values[i]))
|
||||
labels = append(labels, d.String())
|
||||
}
|
||||
t.BarChart.Data = vals
|
||||
t.BarChart.DataLabels = labels
|
||||
t.BarChart.Border.Label = "GC Pauses (last 256)"
|
||||
t.BarChart.BarWidth = 7
|
||||
}
|
||||
t.BarChart.Data = vals
|
||||
t.BarChart.DataLabels = labels
|
||||
t.BarChart.Border.Label = fmt.Sprintf("%v", len(counts))
|
||||
|
||||
t.Relayout()
|
||||
|
||||
var widgets []termui.Bufferer
|
||||
widgets = append(widgets, t.Title, t.Status, t.Sparkline, t.BarChart)
|
||||
widgets = append(widgets, t.Title, t.Status, t.Sparkline)
|
||||
if data.HasBarchart {
|
||||
widgets = append(widgets, t.BarChart)
|
||||
}
|
||||
for _, par := range t.Pars {
|
||||
widgets = append(widgets, par)
|
||||
}
|
||||
|
@ -185,15 +194,19 @@ func (t *TermUISingle) Relayout() {
|
|||
h -= secondRowH
|
||||
|
||||
// Third row: Sparklines
|
||||
calcHeight := len(t.Sparkline.Lines) * 2
|
||||
if calcHeight > (h / 2) {
|
||||
calcHeight = h / 2
|
||||
}
|
||||
|
||||
t.Sparkline.Width = tw
|
||||
t.Sparkline.Height = h / 2
|
||||
t.Sparkline.Height = calcHeight
|
||||
t.Sparkline.Y = th - h
|
||||
|
||||
// Fourth row: Barchart
|
||||
t.BarChart.Width = tw
|
||||
t.BarChart.Height = h / 2
|
||||
t.BarChart.Y = th - h/2
|
||||
t.BarChart.BarWidth = 10
|
||||
t.BarChart.Height = h - calcHeight
|
||||
t.BarChart.Y = th - t.BarChart.Height
|
||||
}
|
||||
|
||||
func formatMax(max interface{}) string {
|
||||
|
|
26
var.go
26
var.go
|
@ -74,6 +74,10 @@ func (v *Number) String() string {
|
|||
return fmt.Sprintf("%.02f", v.val)
|
||||
}
|
||||
func (v *Number) Set(j *jason.Value) {
|
||||
if j == nil {
|
||||
v.val = 0
|
||||
return
|
||||
}
|
||||
if n, err := j.Float64(); err == nil {
|
||||
v.val = n
|
||||
} else if n, err := j.Int64(); err == nil {
|
||||
|
@ -98,6 +102,10 @@ func (v *Memory) String() string {
|
|||
return fmt.Sprintf("%s", byten.Size(v.bytes))
|
||||
}
|
||||
func (v *Memory) Set(j *jason.Value) {
|
||||
if j == nil {
|
||||
v.bytes = 0
|
||||
return
|
||||
}
|
||||
if n, err := j.Int64(); err == nil {
|
||||
v.bytes = n
|
||||
} else {
|
||||
|
@ -122,6 +130,10 @@ func (v *Duration) String() string {
|
|||
}
|
||||
|
||||
func (v *Duration) Set(j *jason.Value) {
|
||||
if j == nil {
|
||||
v.dur = 0
|
||||
return
|
||||
}
|
||||
if n, err := j.Int64(); err == nil {
|
||||
v.dur = time.Duration(n)
|
||||
} else if n, err := j.Float64(); err == nil {
|
||||
|
@ -145,6 +157,10 @@ type String struct {
|
|||
func (v *String) Kind() VarKind { return KindString }
|
||||
func (v *String) String() string { return v.str }
|
||||
func (v *String) Set(j *jason.Value) {
|
||||
if j == nil {
|
||||
v.str = "N/A"
|
||||
return
|
||||
}
|
||||
if n, err := j.String(); err == nil {
|
||||
v.str = n
|
||||
} else {
|
||||
|
@ -165,6 +181,9 @@ func (v *GCPauses) Kind() VarKind { return KindGCPauses }
|
|||
func (v *GCPauses) String() string { return "" }
|
||||
func (v *GCPauses) Set(j *jason.Value) {
|
||||
v.pauses = [256]uint64{}
|
||||
if j == nil {
|
||||
return
|
||||
}
|
||||
if arr, err := j.Array(); err == nil {
|
||||
for i := 0; i < len(arr); i++ {
|
||||
p, _ := arr[i].Int64()
|
||||
|
@ -175,7 +194,12 @@ func (v *GCPauses) Set(j *jason.Value) {
|
|||
func (v *GCPauses) Histogram(bins int) *Histogram {
|
||||
hist := NewHistogram(bins)
|
||||
for i := 0; i < 256; i++ {
|
||||
hist.Add(v.pauses[i])
|
||||
// we ignore zeros, since
|
||||
// its never the case, but
|
||||
// we have zeros on the very beginning
|
||||
if v.pauses[i] > 0 {
|
||||
hist.Add(v.pauses[i])
|
||||
}
|
||||
}
|
||||
return hist
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue