func (this *Redis) drawDashboard() { termui.UseTheme("helloworld") ops := termui.NewSparkline() ops.Title = "ops over the last 2h" ops.Height = 6 ops.LineColor = termui.ColorGreen opsDatas := []int{} res, err := this.queryInfluxDB(`SELECT sum("value") FROM "redis.ops.gauge" WHERE time > now() - 2h GROUP BY time(1m) fill(0)`) swallow(err) for _, cols := range res[0].Series[0].Values { f, _ := cols[1].(json.Number).Float64() opsDatas = append(opsDatas, int(f)) } ops.Data = opsDatas rx := termui.NewSparkline() rx.Title = "rx over the last 2h" rx.Height = 6 rx.LineColor = termui.ColorCyan rxDatas := []int{} res, err = this.queryInfluxDB(`SELECT sum("value") FROM "redis.rx.kbps.gauge" WHERE time > now() - 2h GROUP BY time(1m) fill(0)`) swallow(err) for _, cols := range res[0].Series[0].Values { f, _ := cols[1].(json.Number).Float64() rxDatas = append(rxDatas, int(f)) } rx.Data = rxDatas tx := termui.NewSparkline() tx.Title = "tx over the last 2h" tx.Height = 6 tx.LineColor = termui.ColorYellow txDatas := []int{} res, err = this.queryInfluxDB(`SELECT sum("value") FROM "redis.tx.kbps.gauge" WHERE time > now() - 2h GROUP BY time(1m) fill(0)`) swallow(err) for _, cols := range res[0].Series[0].Values { f, _ := cols[1].(json.Number).Float64() txDatas = append(txDatas, int(f)) } tx.Data = txDatas spls := termui.NewSparklines(ops, rx, tx) spls.Width = this.w spls.Height = this.h spls.HasBorder = false termui.Render(spls) }
func drawDashboardByHour() { lock.Lock() commitByHours := make(map[int]int) for _, evt := range events { if hook, ok := evt.(*Webhook); ok { for _, cmt := range hook.Commits { t, _ := time.Parse(time.RFC3339, cmt.Timestamp) if _, present := commitByHours[t.Hour()]; present { commitByHours[t.Hour()]++ } else { commitByHours[t.Hour()] = 1 } } } } lock.Unlock() sortedHours := make([]int, 0, len(commitByHours)) for hour, _ := range commitByHours { sortedHours = append(sortedHours, hour) } sort.Ints(sortedHours) termbox.Clear(coldef, coldef) termui.UseTheme("helloworld") bc := termui.NewBarChart() data := []int{} bclabels := []string{} for _, hour := range sortedHours { data = append(data, commitByHours[hour]) bclabels = append(bclabels, fmt.Sprintf("%02d", hour)) } bc.Border.Label = "Commit by hour" bc.Data = data bc.Width = w bc.Height = h bc.DataLabels = bclabels bc.TextColor = termui.ColorGreen bc.BarColor = termui.ColorRed bc.NumColor = termui.ColorYellow termui.Render(bc) }
func (this *Histogram) drawAll(offsetTs []time.Time, offsets []int64, netTs []time.Time, rx []int64, tx []int64) { err := termui.Init() swallow(err) defer termui.Close() termui.UseTheme("helloworld") w, h := termbox.Size() bc1 := termui.NewBarChart() bc1.Border.Label = "Messages Produced/in million" data := make([]int, 0) for _, off := range offsets { data = append(data, int(off/1000000)) // in million } bclabels := make([]string, 0) for _, t := range offsetTs { bclabels = append(bclabels, fmt.Sprintf("%02d", t.Hour())) } bc1.Data = data bc1.Width = w bc1.SetY(0) bc1.Height = h / 3 bc1.DataLabels = bclabels bc1.TextColor = termui.ColorWhite bc1.BarColor = termui.ColorRed bc1.NumColor = termui.ColorYellow bclabels = make([]string, 0) // shared between bc2 and bc3 for _, t := range netTs { bclabels = append(bclabels, fmt.Sprintf("%02d", t.Hour())) } bc2 := termui.NewBarChart() bc2.Border.Label = "Network RX/in 10GB" data = make([]int, 0) for _, r := range rx { data = append(data, int(r>>30)/10) } bc2.Data = data bc2.Width = w bc2.SetY(h / 3) bc2.Height = h / 3 bc2.DataLabels = bclabels bc2.TextColor = termui.ColorGreen bc2.BarColor = termui.ColorRed bc2.NumColor = termui.ColorYellow bc3 := termui.NewBarChart() bc3.Border.Label = "Network TX/in 10GB" data = make([]int, 0) for _, t := range tx { data = append(data, int(t>>30)/10) } bc3.Data = data bc3.Width = w bc3.SetY(h * 2 / 3) bc3.Height = h / 3 bc3.DataLabels = bclabels bc3.TextColor = termui.ColorGreen bc3.BarColor = termui.ColorRed bc3.NumColor = termui.ColorYellow termui.Render(bc1, bc2, bc3) termbox.PollEvent() }
func drawDashboard() { hosts = HostsOfGroup(group) data = make([][]float64, len(hosts)) // title titlePanel := ui.NewPar(fmt.Sprintf("%s: %s / %v", group, itemName, tick*dataSize)) titlePanel.Height = titleHeight titlePanel.PaddingLeft = 1 titlePanel.HasBorder = false titlePanel.TextFgColor = ui.ColorCyan // charts charts := make([]*ui.LineChart, 0) for i := 0; i < len(data); i++ { chart := ui.NewLineChart() chart.Border.Label = hosts[i].Name chart.Data = fetchData(i, dataSize) chart.Height = panelHeight chart.PaddingTop = chartPaddingTop chart.AxesColor = axesColor chart.LineColor = lineColor charts = append(charts, chart) } draw := func(size int) { if size > 0 { for i := 0; i < len(data); i++ { charts[i].Data = fetchData(i, size) } } ui.Render(ui.Body) } err := ui.Init() must(err) defer ui.Close() ui.UseTheme(uiTheme) // auto layout rows := make([]*ui.Row, 1) rows[0] = ui.NewRow(ui.NewCol(panelSpan*panelsPerRow, panelOffset, titlePanel)) for i := 0; i < len(hosts); i += panelsPerRow { if i+1 == len(hosts) { // the last single panel rows = append(rows, ui.NewRow(ui.NewCol(panelSpan, panelOffset, charts[i]))) } else { rows = append(rows, ui.NewRow(ui.NewCol(panelSpan, panelOffset, charts[i]), ui.NewCol(panelSpan, panelOffset, charts[i+1]))) } } ui.Body.AddRows(rows...) ui.Body.Align() // draw the history data draw(0) evt := make(chan tm.Event) go func() { for { evt <- tm.PollEvent() } }() for { select { case e := <-evt: if e.Type == tm.EventKey && e.Ch == 'q' { return } if e.Type == tm.EventResize { ui.Body.Width = ui.TermWidth() ui.Body.Align() } case <-time.After(tick): draw(1) } } }
func (this *Top) drawDashboard() { err := termui.Init() swallow(err) defer termui.Close() termui.UseTheme("helloworld") maxRound := termui.TermWidth() / 2 refreshProducerData := func(round int) []float64 { this.showAndResetCounters() if round%maxRound == (maxRound - 5) { this.mu.Lock() tailLen := len(this.totalMps) - 2 tail := this.totalMps[tailLen:] this.totalMps = make([]float64, 2, 1000) copy(this.totalMps, tail) this.mu.Unlock() } return this.totalMps } refreshConsumerData := func(round int) []float64 { if round%maxRound == (maxRound - 5) { this.mu.Lock() tailLen := len(this.totalConsumerMps) - 2 tail := this.totalConsumerMps[tailLen:] this.totalConsumerMps = make([]float64, 2, 1000) copy(this.totalConsumerMps, tail) this.mu.Unlock() } return this.totalConsumerMps } producerChart := termui.NewLineChart() producerChart.Mode = "dot" producerChart.Border.Label = fmt.Sprintf("producer mps totals: %s %s %s", this.zone, this.clusterPattern, this.topicPattern) producerChart.Data = refreshProducerData(0) producerChart.Width = termui.TermWidth() / 2 producerChart.Height = termui.TermHeight() producerChart.X = 0 producerChart.Y = 0 producerChart.AxesColor = termui.ColorWhite producerChart.LineColor = termui.ColorGreen | termui.AttrBold consumerChart := termui.NewLineChart() consumerChart.Mode = "dot" consumerChart.Border.Label = fmt.Sprintf("consumer mps totals: %s %s %s", this.zone, this.clusterPattern, this.topicPattern) consumerChart.Data = refreshConsumerData(0) consumerChart.Width = termui.TermWidth() / 2 consumerChart.Height = termui.TermHeight() consumerChart.X = termui.TermWidth() / 2 consumerChart.Y = 0 consumerChart.AxesColor = termui.ColorWhite consumerChart.LineColor = termui.ColorRed | termui.AttrBold evt := make(chan termbox.Event) go func() { for { evt <- termbox.PollEvent() } }() termui.Render(producerChart, consumerChart) tick := time.NewTicker(this.topInterval) defer tick.Stop() rounds := 0 for { select { case e := <-evt: if e.Type == termbox.EventKey && e.Ch == 'q' { return } case <-tick.C: // refresh data, and skip the first 2 rounds rounds++ if rounds > 1 { producerChart.Data = refreshProducerData(rounds) consumerChart.Data = refreshConsumerData(rounds) termui.Render(producerChart, consumerChart) } } } }