basic alerter functionality added
This commit is contained in:
parent
7db33312b6
commit
97cee1ec94
|
@ -0,0 +1,41 @@
|
||||||
|
package component
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sqshq/sampler/console"
|
||||||
|
"github.com/sqshq/sampler/data"
|
||||||
|
ui "github.com/sqshq/termui"
|
||||||
|
"image"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Alerter struct {
|
||||||
|
channel <-chan data.Alert
|
||||||
|
alert *data.Alert
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAlerter(channel <-chan data.Alert) *Alerter {
|
||||||
|
alerter := Alerter{channel: channel}
|
||||||
|
alerter.consume()
|
||||||
|
return &alerter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Alerter) consume() {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case alert := <-a.channel:
|
||||||
|
a.alert = &alert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Alerter) RenderAlert(buffer *ui.Buffer, area image.Rectangle) {
|
||||||
|
|
||||||
|
if a.alert == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.Fill(ui.NewCell(' ', ui.NewStyle(console.ColorBlack)), area)
|
||||||
|
buffer.SetString(a.alert.Title, ui.NewStyle(console.ColorWhite), getMiddlePoint(area, a.alert.Title, -1))
|
||||||
|
buffer.SetString(a.alert.Text, ui.NewStyle(console.ColorWhite), getMiddlePoint(area, a.alert.Text, 0))
|
||||||
|
}
|
|
@ -130,14 +130,14 @@ func (m *Menu) renderHighlight(buffer *ui.Buffer) {
|
||||||
buffer.SetString(
|
buffer.SetString(
|
||||||
optionsText,
|
optionsText,
|
||||||
ui.NewStyle(console.ColorDarkGrey),
|
ui.NewStyle(console.ColorDarkGrey),
|
||||||
getMiddlePoint(m.Block, optionsText, -1),
|
getMiddlePoint(m.Block.Rectangle, optionsText, -1),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m.printAllDirectionsArrowSign(buffer, -2)
|
m.printAllDirectionsArrowSign(buffer, -2)
|
||||||
|
|
||||||
arrowsTextPoint := getMiddlePoint(m.Block, arrowsText, 2)
|
arrowsTextPoint := getMiddlePoint(m.Block.Rectangle, arrowsText, 2)
|
||||||
if arrowsTextPoint.Y+1 < m.Inner.Max.Y {
|
if arrowsTextPoint.Y+1 < m.Inner.Max.Y {
|
||||||
buffer.SetString(
|
buffer.SetString(
|
||||||
arrowsText,
|
arrowsText,
|
||||||
|
@ -146,16 +146,16 @@ func (m *Menu) renderHighlight(buffer *ui.Buffer) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
optionsTextPoint := getMiddlePoint(m.Block, optionsText, 3)
|
optionsTextPoint := getMiddlePoint(m.Block.Rectangle, optionsText, 3)
|
||||||
if optionsTextPoint.Y+1 < m.Inner.Max.Y {
|
if optionsTextPoint.Y+1 < m.Inner.Max.Y {
|
||||||
buffer.SetString(
|
buffer.SetString(
|
||||||
optionsText,
|
optionsText,
|
||||||
ui.NewStyle(console.ColorDarkGrey),
|
ui.NewStyle(console.ColorDarkGrey),
|
||||||
getMiddlePoint(m.Block, optionsText, 3),
|
getMiddlePoint(m.Block.Rectangle, optionsText, 3),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
resumeTextPoint := getMiddlePoint(m.Block, resumeText, 4)
|
resumeTextPoint := getMiddlePoint(m.Block.Rectangle, resumeText, 4)
|
||||||
if resumeTextPoint.Y+1 < m.Inner.Max.Y {
|
if resumeTextPoint.Y+1 < m.Inner.Max.Y {
|
||||||
buffer.SetString(
|
buffer.SetString(
|
||||||
resumeText,
|
resumeText,
|
||||||
|
@ -170,12 +170,12 @@ func (m *Menu) renderMoveAndResize(buffer *ui.Buffer) {
|
||||||
saveText := "<ENTER> to save changes"
|
saveText := "<ENTER> to save changes"
|
||||||
|
|
||||||
if m.Dy() <= minimalMenuHeight {
|
if m.Dy() <= minimalMenuHeight {
|
||||||
buffer.SetString(saveText, ui.NewStyle(console.ColorDarkGrey), getMiddlePoint(m.Block, saveText, -1))
|
buffer.SetString(saveText, ui.NewStyle(console.ColorDarkGrey), getMiddlePoint(m.Block.Rectangle, saveText, -1))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m.printAllDirectionsArrowSign(buffer, -1)
|
m.printAllDirectionsArrowSign(buffer, -1)
|
||||||
buffer.SetString(saveText, ui.NewStyle(console.ColorDarkGrey), getMiddlePoint(m.Block, saveText, 3))
|
buffer.SetString(saveText, ui.NewStyle(console.ColorDarkGrey), getMiddlePoint(m.Block.Rectangle, saveText, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Menu) printAllDirectionsArrowSign(buffer *ui.Buffer, y int) {
|
func (m *Menu) printAllDirectionsArrowSign(buffer *ui.Buffer, y int) {
|
||||||
|
@ -190,7 +190,7 @@ func (m *Menu) printAllDirectionsArrowSign(buffer *ui.Buffer, y int) {
|
||||||
buffer.SetString(
|
buffer.SetString(
|
||||||
a,
|
a,
|
||||||
ui.NewStyle(console.ColorOlive),
|
ui.NewStyle(console.ColorOlive),
|
||||||
getMiddlePoint(m.Block, a, i+y),
|
getMiddlePoint(m.Block.Rectangle, a, i+y),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ func (m *Menu) renderOptions(buffer *ui.Buffer) {
|
||||||
|
|
||||||
if option != MenuOptionPinpoint || m.component.Type == config.TypeRunChart {
|
if option != MenuOptionPinpoint || m.component.Type == config.TypeRunChart {
|
||||||
offset += 2
|
offset += 2
|
||||||
point := getMiddlePoint(m.Block, string(option), offset-5)
|
point := getMiddlePoint(m.Block.Rectangle, string(option), offset-5)
|
||||||
buffer.SetString(string(option), style, point)
|
buffer.SetString(string(option), style, point)
|
||||||
//if point.In(m.GetRect()) {
|
//if point.In(m.GetRect()) {
|
||||||
// buffer.SetString(string(option), style, point)
|
// buffer.SetString(string(option), style, point)
|
||||||
|
@ -243,6 +243,7 @@ func (m *Menu) drawInnerBorder(buffer *ui.Buffer) {
|
||||||
buffer.SetCell(ui.Cell{ui.BOTTOM_RIGHT, m.BorderStyle}, image.Pt(m.Max.X-3, m.Max.Y-2))
|
buffer.SetCell(ui.Cell{ui.BOTTOM_RIGHT, m.BorderStyle}, image.Pt(m.Max.X-3, m.Max.Y-2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMiddlePoint(block ui.Block, text string, offset int) image.Point {
|
// TODO move to utils
|
||||||
return image.Pt(block.Min.X+block.Dx()/2-len(text)/2, block.Max.Y-block.Dy()/2+offset)
|
func getMiddlePoint(rectangle image.Rectangle, text string, offset int) image.Point {
|
||||||
|
return image.Pt(rectangle.Min.X+rectangle.Dx()/2-len(text)/2, rectangle.Max.Y-rectangle.Dy()/2+offset)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package runchart
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/sqshq/sampler/component"
|
||||||
"github.com/sqshq/sampler/config"
|
"github.com/sqshq/sampler/config"
|
||||||
"github.com/sqshq/sampler/console"
|
"github.com/sqshq/sampler/console"
|
||||||
"github.com/sqshq/sampler/data"
|
"github.com/sqshq/sampler/data"
|
||||||
|
@ -38,6 +39,7 @@ const (
|
||||||
type RunChart struct {
|
type RunChart struct {
|
||||||
ui.Block
|
ui.Block
|
||||||
data.Consumer
|
data.Consumer
|
||||||
|
*component.Alerter
|
||||||
lines []TimeLine
|
lines []TimeLine
|
||||||
grid ChartGrid
|
grid ChartGrid
|
||||||
timescale time.Duration
|
timescale time.Duration
|
||||||
|
@ -75,12 +77,14 @@ type ValueExtrema struct {
|
||||||
|
|
||||||
func NewRunChart(c config.RunChartConfig, l Legend) *RunChart {
|
func NewRunChart(c config.RunChartConfig, l Legend) *RunChart {
|
||||||
|
|
||||||
|
consumer := data.NewConsumer()
|
||||||
block := *ui.NewBlock()
|
block := *ui.NewBlock()
|
||||||
block.Title = c.Title
|
block.Title = c.Title
|
||||||
|
|
||||||
chart := RunChart{
|
chart := RunChart{
|
||||||
Block: block,
|
Block: block,
|
||||||
Consumer: data.NewConsumer(),
|
Consumer: consumer,
|
||||||
|
Alerter: component.NewAlerter(consumer.AlertChannel),
|
||||||
lines: []TimeLine{},
|
lines: []TimeLine{},
|
||||||
timescale: calculateTimescale(*c.RefreshRateMs),
|
timescale: calculateTimescale(*c.RefreshRateMs),
|
||||||
mutex: &sync.Mutex{},
|
mutex: &sync.Mutex{},
|
||||||
|
@ -128,6 +132,7 @@ func (c *RunChart) Draw(buffer *ui.Buffer) {
|
||||||
c.renderAxes(buffer)
|
c.renderAxes(buffer)
|
||||||
c.renderLines(buffer, drawArea)
|
c.renderLines(buffer, drawArea)
|
||||||
c.renderLegend(buffer, drawArea)
|
c.renderLegend(buffer, drawArea)
|
||||||
|
c.RenderAlert(buffer, c.Rectangle)
|
||||||
c.mutex.Unlock()
|
c.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ runcharts:
|
||||||
h: 16
|
h: 16
|
||||||
triggers:
|
triggers:
|
||||||
- title: LATENCY
|
- title: LATENCY
|
||||||
condition: echo "$prev < 0.4 && $cur > 0.4" |bc -l
|
condition: echo "$prev < 0.2 && $cur > 0.2" |bc -l
|
||||||
actions:
|
actions:
|
||||||
terminal-bell: true
|
terminal-bell: true
|
||||||
sound: true
|
sound: true
|
||||||
|
|
|
@ -20,7 +20,7 @@ const (
|
||||||
ColorOrange ui.Color = 166
|
ColorOrange ui.Color = 166
|
||||||
ColorPurple ui.Color = 129
|
ColorPurple ui.Color = 129
|
||||||
ColorGreen ui.Color = 64
|
ColorGreen ui.Color = 64
|
||||||
ColorDarkGrey ui.Color = 235
|
ColorDarkGrey ui.Color = 238
|
||||||
ColorGrey ui.Color = 242
|
ColorGrey ui.Color = 242
|
||||||
ColorWhite ui.Color = 15
|
ColorWhite ui.Color = 15
|
||||||
ColorBlack ui.Color = 0
|
ColorBlack ui.Color = 0
|
||||||
|
|
|
@ -77,9 +77,9 @@ func (t *Trigger) Execute(sample Sample) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.actions.visual {
|
if t.actions.visual {
|
||||||
//t.consumer.AlertChannel <- Alert{
|
t.consumer.AlertChannel <- Alert{
|
||||||
// Title: "TRIGGER ALERT", Text: sample.Label,
|
Title: t.title, Text: fmt.Sprintf("%s value: %v", sample.Label, sample.Value),
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.actions.script != nil {
|
if t.actions.script != nil {
|
||||||
|
|
Loading…
Reference in New Issue