Add BarChart for GC pauses

This commit is contained in:
Ivan Daniluk 2016-11-13 12:05:26 +01:00
parent 86e5c63eaf
commit 794515330a
4 changed files with 72 additions and 23 deletions

13
data.go
View File

@ -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),
}
}

View File

@ -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)
}

View File

@ -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
View File

@ -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
}