diff --git a/component/alerter.go b/component/alerter.go new file mode 100644 index 0000000..8bc94da --- /dev/null +++ b/component/alerter.go @@ -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)) +} diff --git a/component/menu.go b/component/menu.go index 6c26403..081428a 100644 --- a/component/menu.go +++ b/component/menu.go @@ -130,14 +130,14 @@ func (m *Menu) renderHighlight(buffer *ui.Buffer) { buffer.SetString( optionsText, ui.NewStyle(console.ColorDarkGrey), - getMiddlePoint(m.Block, optionsText, -1), + getMiddlePoint(m.Block.Rectangle, optionsText, -1), ) return } 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 { buffer.SetString( 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 { buffer.SetString( optionsText, 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 { buffer.SetString( resumeText, @@ -170,12 +170,12 @@ func (m *Menu) renderMoveAndResize(buffer *ui.Buffer) { saveText := " to save changes" 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 } 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) { @@ -190,7 +190,7 @@ func (m *Menu) printAllDirectionsArrowSign(buffer *ui.Buffer, y int) { buffer.SetString( a, 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 { 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) //if point.In(m.GetRect()) { // 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)) } -func getMiddlePoint(block ui.Block, text string, offset int) image.Point { - return image.Pt(block.Min.X+block.Dx()/2-len(text)/2, block.Max.Y-block.Dy()/2+offset) +// TODO move to utils +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) } diff --git a/component/runchart/runchart.go b/component/runchart/runchart.go index ba99632..1caa8e2 100644 --- a/component/runchart/runchart.go +++ b/component/runchart/runchart.go @@ -2,6 +2,7 @@ package runchart import ( "fmt" + "github.com/sqshq/sampler/component" "github.com/sqshq/sampler/config" "github.com/sqshq/sampler/console" "github.com/sqshq/sampler/data" @@ -38,6 +39,7 @@ const ( type RunChart struct { ui.Block data.Consumer + *component.Alerter lines []TimeLine grid ChartGrid timescale time.Duration @@ -75,12 +77,14 @@ type ValueExtrema struct { func NewRunChart(c config.RunChartConfig, l Legend) *RunChart { + consumer := data.NewConsumer() block := *ui.NewBlock() block.Title = c.Title chart := RunChart{ Block: block, - Consumer: data.NewConsumer(), + Consumer: consumer, + Alerter: component.NewAlerter(consumer.AlertChannel), lines: []TimeLine{}, timescale: calculateTimescale(*c.RefreshRateMs), mutex: &sync.Mutex{}, @@ -128,6 +132,7 @@ func (c *RunChart) Draw(buffer *ui.Buffer) { c.renderAxes(buffer) c.renderLines(buffer, drawArea) c.renderLegend(buffer, drawArea) + c.RenderAlert(buffer, c.Rectangle) c.mutex.Unlock() } diff --git a/config.yml b/config.yml index 9743d1f..736b93b 100644 --- a/config.yml +++ b/config.yml @@ -8,7 +8,7 @@ runcharts: h: 16 triggers: - title: LATENCY - condition: echo "$prev < 0.4 && $cur > 0.4" |bc -l + condition: echo "$prev < 0.2 && $cur > 0.2" |bc -l actions: terminal-bell: true sound: true diff --git a/console/palette.go b/console/palette.go index e7821a6..095192b 100644 --- a/console/palette.go +++ b/console/palette.go @@ -20,7 +20,7 @@ const ( ColorOrange ui.Color = 166 ColorPurple ui.Color = 129 ColorGreen ui.Color = 64 - ColorDarkGrey ui.Color = 235 + ColorDarkGrey ui.Color = 238 ColorGrey ui.Color = 242 ColorWhite ui.Color = 15 ColorBlack ui.Color = 0 diff --git a/data/trigger.go b/data/trigger.go index c7c5fc7..3b58fc5 100644 --- a/data/trigger.go +++ b/data/trigger.go @@ -77,9 +77,9 @@ func (t *Trigger) Execute(sample Sample) { } if t.actions.visual { - //t.consumer.AlertChannel <- Alert{ - // Title: "TRIGGER ALERT", Text: sample.Label, - //} + t.consumer.AlertChannel <- Alert{ + Title: t.title, Text: fmt.Sprintf("%s value: %v", sample.Label, sample.Value), + } } if t.actions.script != nil {