From 8427b0c81d83db73494689b7f1b2246bb29d2e63 Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Sat, 8 Jun 2019 21:34:43 +0000 Subject: [PATCH] initial refactor of all column widgets to standard interface --- container/main.go | 15 ++-- cwidgets/compact/gauge.go | 55 ++++++++++++- cwidgets/compact/main.go | 149 +++++++++++++----------------------- cwidgets/compact/setters.go | 48 ------------ cwidgets/compact/status.go | 26 +++++-- cwidgets/compact/text.go | 58 ++++++++++++-- cwidgets/main.go | 2 +- cwidgets/single/main.go | 12 +-- models/main.go | 11 +++ 9 files changed, 198 insertions(+), 178 deletions(-) delete mode 100644 cwidgets/compact/setters.go diff --git a/container/main.go b/container/main.go index 416b878..660e5cc 100644 --- a/container/main.go +++ b/container/main.go @@ -21,7 +21,7 @@ const ( type Container struct { models.Metrics Id string - Meta map[string]string + Meta models.Meta Widgets *compact.Compact Display bool // display this container in compact view updater cwidgets.WidgetUpdater @@ -34,7 +34,7 @@ func New(id string, collector collector.Collector, manager manager.Manager) *Con return &Container{ Metrics: models.NewMetrics(), Id: id, - Meta: make(map[string]string), + Meta: models.NewMeta(), Widgets: widgets, updater: widgets, collector: collector, @@ -44,21 +44,16 @@ func New(id string, collector collector.Collector, manager manager.Manager) *Con func (c *Container) SetUpdater(u cwidgets.WidgetUpdater) { c.updater = u - for k, v := range c.Meta { - c.updater.SetMeta(k, v) - } + c.updater.SetMeta(c.Meta) } func (c *Container) SetMeta(k, v string) { c.Meta[k] = v - c.updater.SetMeta(k, v) + c.updater.SetMeta(c.Meta) } func (c *Container) GetMeta(k string) string { - if v, ok := c.Meta[k]; ok { - return v - } - return "" + return c.Meta.Get(k) } func (c *Container) SetState(s string) { diff --git a/cwidgets/compact/gauge.go b/cwidgets/compact/gauge.go index 481fb32..b22042f 100644 --- a/cwidgets/compact/gauge.go +++ b/cwidgets/compact/gauge.go @@ -1,21 +1,49 @@ package compact import ( + "fmt" + + "github.com/bcicen/ctop/cwidgets" + "github.com/bcicen/ctop/models" ui "github.com/gizak/termui" ) +type CPUCol struct { + *GaugeCol +} + +func (w *CPUCol) SetMetrics(m models.Metrics) { + val := m.CPUUtil + w.BarColor = colorScale(val) + w.Label = fmt.Sprintf("%d%%", val) + + if val > 100 { + val = 100 + } + w.Percent = val +} + +type MemCol struct { + *GaugeCol +} + +func (w *MemCol) SetMetrics(m models.Metrics) { + w.BarColor = ui.ThemeAttr("gauge.bar.bg") + w.Label = fmt.Sprintf("%s / %s", cwidgets.ByteFormat(m.MemUsage), cwidgets.ByteFormat(m.MemLimit)) + w.Percent = m.MemPercent +} + type GaugeCol struct { *ui.Gauge } func NewGaugeCol() *GaugeCol { - g := ui.NewGauge() + g := &GaugeCol{ui.NewGauge()} g.Height = 1 g.Border = false - g.Percent = 0 g.PaddingBottom = 0 - g.Label = "-" - return &GaugeCol{g} + g.Reset() + return g } func (w *GaugeCol) Reset() { @@ -23,11 +51,30 @@ func (w *GaugeCol) Reset() { w.Percent = 0 } +func (w *GaugeCol) Buffer() ui.Buffer { + // if bar would not otherwise be visible, set a minimum + // percentage value and low-contrast color for structure + if w.Percent < 5 { + w.Percent = 5 + w.BarColor = ui.ColorBlack + } + + return w.Gauge.Buffer() +} + +// GaugeCol implements CompactCol +func (w *GaugeCol) SetMeta(models.Meta) {} + +// GaugeCol implements CompactCol +func (w *GaugeCol) SetMetrics(models.Metrics) {} + +// GaugeCol implements CompactCol func (w *GaugeCol) Highlight() { w.Bg = ui.ThemeAttr("par.text.fg") w.PercentColor = ui.ThemeAttr("par.text.hi") } +// GaugeCol implements CompactCol func (w *GaugeCol) UnHighlight() { w.Bg = ui.ThemeAttr("par.text.bg") w.PercentColor = ui.ThemeAttr("par.text.bg") diff --git a/cwidgets/compact/main.go b/cwidgets/compact/main.go index af948fc..9f6cef4 100644 --- a/cwidgets/compact/main.go +++ b/cwidgets/compact/main.go @@ -9,16 +9,18 @@ import ( var log = logging.Init() +type CompactCol interface { + ui.GridBufferer + Reset() + Highlight() + UnHighlight() + SetMeta(models.Meta) + SetMetrics(models.Metrics) +} + type Compact struct { - Status *Status - Name *TextCol - Cid *TextCol - Cpu *GaugeCol - Mem *GaugeCol - Net *TextCol - IO *TextCol - Pids *TextCol Bg *RowBg + Cols []CompactCol X, Y int Width int Height int @@ -30,64 +32,44 @@ func NewCompact(id string) *Compact { id = id[:12] } row := &Compact{ - Status: NewStatus(), - Name: NewTextCol("-"), - Cid: NewTextCol(id), - Cpu: NewGaugeCol(), - Mem: NewGaugeCol(), - Net: NewTextCol("-"), - IO: NewTextCol("-"), - Pids: NewTextCol("-"), - Bg: NewRowBg(), + Bg: NewRowBg(), + Cols: []CompactCol{ + NewStatus(), + &NameCol{NewTextCol("-")}, + &CIDCol{NewTextCol(id)}, + &CPUCol{NewGaugeCol()}, + &MemCol{NewGaugeCol()}, + &NetCol{NewTextCol("-")}, + &IOCol{NewTextCol("-")}, + &PIDCol{NewTextCol("-")}, + }, X: 1, Height: 1, } return row } -//func (row *Compact) ToggleExpand() { -//if row.Height == 1 { -//row.Height = 4 -//} else { -//row.Height = 1 -//} -//} - -func (row *Compact) SetMeta(k, v string) { - switch k { - case "name": - row.Name.Set(v) - case "state": - row.Status.Set(v) - case "health": - row.Status.SetHealth(v) +func (row *Compact) SetMeta(m models.Meta) { + for _, w := range row.Cols { + w.SetMeta(m) } } func (row *Compact) SetMetrics(m models.Metrics) { - row.SetCPU(m.CPUUtil) - row.SetNet(m.NetRx, m.NetTx) - row.SetMem(m.MemUsage, m.MemLimit, m.MemPercent) - row.SetIO(m.IOBytesRead, m.IOBytesWrite) - row.SetPids(m.Pids) + for _, w := range row.Cols { + w.SetMetrics(m) + } } -// Set gauges, counters to default unread values +// Set gauges, counters, etc. to default unread values func (row *Compact) Reset() { - row.Cpu.Reset() - row.Mem.Reset() - row.Net.Reset() - row.IO.Reset() - row.Pids.Reset() + for _, w := range row.Cols { + w.Reset() + } } -func (row *Compact) GetHeight() int { - return row.Height -} - -func (row *Compact) SetX(x int) { - row.X = x -} +func (row *Compact) GetHeight() int { return row.Height } +func (row *Compact) SetX(x int) { row.X = x } func (row *Compact) SetY(y int) { if y == row.Y { @@ -95,8 +77,8 @@ func (row *Compact) SetY(y int) { } row.Bg.Y = y - for _, col := range row.all() { - col.SetY(y) + for _, w := range row.Cols { + w.SetY(y) } row.Y = y } @@ -111,15 +93,17 @@ func (row *Compact) SetWidth(width int) { row.Bg.SetWidth(width) autoWidth := calcWidth(width) - for n, col := range row.all() { + for n, w := range row.Cols { + // set static width, if provided if colWidths[n] != 0 { - col.SetX(x) - col.SetWidth(colWidths[n]) + w.SetX(x) + w.SetWidth(colWidths[n]) x += colWidths[n] continue } - col.SetX(x) - col.SetWidth(autoWidth) + // else use auto width + w.SetX(x) + w.SetWidth(autoWidth) x += autoWidth + colSpacing } row.Width = width @@ -127,55 +111,28 @@ func (row *Compact) SetWidth(width int) { func (row *Compact) Buffer() ui.Buffer { buf := ui.NewBuffer() - buf.Merge(row.Bg.Buffer()) - buf.Merge(row.Status.Buffer()) - buf.Merge(row.Name.Buffer()) - buf.Merge(row.Cid.Buffer()) - buf.Merge(row.Cpu.Buffer()) - buf.Merge(row.Mem.Buffer()) - buf.Merge(row.Net.Buffer()) - buf.Merge(row.IO.Buffer()) - buf.Merge(row.Pids.Buffer()) + for _, w := range row.Cols { + buf.Merge(w.Buffer()) + } return buf } -func (row *Compact) all() []ui.GridBufferer { - return []ui.GridBufferer{ - row.Status, - row.Name, - row.Cid, - row.Cpu, - row.Mem, - row.Net, - row.IO, - row.Pids, - } -} - func (row *Compact) Highlight() { - row.Name.Highlight() + row.Cols[1].Highlight() if config.GetSwitchVal("fullRowCursor") { - row.Bg.Highlight() - row.Cid.Highlight() - row.Cpu.Highlight() - row.Mem.Highlight() - row.Net.Highlight() - row.IO.Highlight() - row.Pids.Highlight() + for _, w := range row.Cols { + w.Highlight() + } } } func (row *Compact) UnHighlight() { - row.Name.UnHighlight() + row.Cols[1].UnHighlight() if config.GetSwitchVal("fullRowCursor") { - row.Bg.UnHighlight() - row.Cid.UnHighlight() - row.Cpu.UnHighlight() - row.Mem.UnHighlight() - row.Net.UnHighlight() - row.IO.UnHighlight() - row.Pids.UnHighlight() + for _, w := range row.Cols { + w.UnHighlight() + } } } diff --git a/cwidgets/compact/setters.go b/cwidgets/compact/setters.go deleted file mode 100644 index 779991e..0000000 --- a/cwidgets/compact/setters.go +++ /dev/null @@ -1,48 +0,0 @@ -package compact - -import ( - "fmt" - "strconv" - - "github.com/bcicen/ctop/cwidgets" - ui "github.com/gizak/termui" -) - -func (row *Compact) SetNet(rx int64, tx int64) { - label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(rx), cwidgets.ByteFormat(tx)) - row.Net.Set(label) -} - -func (row *Compact) SetIO(read int64, write int64) { - label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(read), cwidgets.ByteFormat(write)) - row.IO.Set(label) -} - -func (row *Compact) SetPids(val int) { - label := strconv.Itoa(val) - row.Pids.Set(label) -} - -func (row *Compact) SetCPU(val int) { - row.Cpu.BarColor = colorScale(val) - row.Cpu.Label = fmt.Sprintf("%s%%", strconv.Itoa(val)) - if val < 5 { - val = 5 - row.Cpu.BarColor = ui.ThemeAttr("gauge.bar.bg") - } - if val > 100 { - val = 100 - } - row.Cpu.Percent = val -} - -func (row *Compact) SetMem(val int64, limit int64, percent int) { - row.Mem.Label = fmt.Sprintf("%s / %s", cwidgets.ByteFormat(val), cwidgets.ByteFormat(limit)) - if percent < 5 { - percent = 5 - row.Mem.BarColor = ui.ColorBlack - } else { - row.Mem.BarColor = ui.ThemeAttr("gauge.bar.bg") - } - row.Mem.Percent = percent -} diff --git a/cwidgets/compact/status.go b/cwidgets/compact/status.go index d6b920f..43c838b 100644 --- a/cwidgets/compact/status.go +++ b/cwidgets/compact/status.go @@ -1,6 +1,7 @@ package compact import ( + "github.com/bcicen/ctop/models" ui "github.com/gizak/termui" ) @@ -24,7 +25,7 @@ func NewStatus() *Status { } s.Height = 1 s.Border = false - s.Set("") + s.setState("") return s } @@ -43,7 +44,18 @@ func (s *Status) Buffer() ui.Buffer { return buf } -func (s *Status) Set(val string) { +func (s *Status) SetMeta(m models.Meta) { + s.setState(m.Get("state")) + s.setHealth(m.Get("health")) +} + +// Status implements CompactCol +func (s *Status) Reset() {} +func (s *Status) SetMetrics(models.Metrics) {} +func (s *Status) Highlight() {} +func (s *Status) UnHighlight() {} + +func (s *Status) setState(val string) { // defaults text := mark color := ui.ColorDefault @@ -60,21 +72,21 @@ func (s *Status) Set(val string) { s.status = ui.TextCells(text, color, ui.ColorDefault) } -func (s *Status) SetHealth(val string) { - if val == "" { - return - } - +func (s *Status) setHealth(val string) { color := ui.ColorDefault mark := healthMark switch val { + case "": + return case "healthy": color = ui.ThemeAttr("status.ok") case "unhealthy": color = ui.ThemeAttr("status.danger") case "starting": color = ui.ThemeAttr("status.warn") + default: + log.Warningf("unknown health state string: \"%v\"", val) } s.health = ui.TextCells(mark, color, ui.ColorDefault) diff --git a/cwidgets/compact/text.go b/cwidgets/compact/text.go index e635e25..ed690a6 100644 --- a/cwidgets/compact/text.go +++ b/cwidgets/compact/text.go @@ -1,9 +1,56 @@ package compact import ( + "fmt" + + "github.com/bcicen/ctop/cwidgets" + "github.com/bcicen/ctop/models" ui "github.com/gizak/termui" ) +type NameCol struct { + *TextCol +} + +func (w *NameCol) SetMeta(m models.Meta) { + if s, ok := m["name"]; ok { + w.Text = s + } +} + +func (w *NameCol) SetMetrics(m models.Metrics) { +} + +type CIDCol struct { + *TextCol +} + +type NetCol struct { + *TextCol +} + +func (w *NetCol) SetMetrics(m models.Metrics) { + label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(m.NetRx), cwidgets.ByteFormat(m.NetTx)) + w.Text = label +} + +type IOCol struct { + *TextCol +} + +func (w *IOCol) SetMetrics(m models.Metrics) { + label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(m.IOBytesRead), cwidgets.ByteFormat(m.IOBytesWrite)) + w.Text = label +} + +type PIDCol struct { + *TextCol +} + +func (w *PIDCol) SetMetrics(m models.Metrics) { + w.Text = fmt.Sprintf("%d", m.Pids) +} + type TextCol struct { *ui.Par } @@ -28,10 +75,7 @@ func (w *TextCol) UnHighlight() { w.TextBgColor = ui.ThemeAttr("par.text.bg") } -func (w *TextCol) Reset() { - w.Text = "-" -} - -func (w *TextCol) Set(s string) { - w.Text = s -} +//func (w *TextCol) Set(s string) { w.Text = s } +func (w *TextCol) Reset() { w.Text = "-" } +func (w *TextCol) SetMeta(models.Meta) {} +func (w *TextCol) SetMetrics(models.Metrics) {} diff --git a/cwidgets/main.go b/cwidgets/main.go index 50e4d2e..fd2f68b 100644 --- a/cwidgets/main.go +++ b/cwidgets/main.go @@ -8,6 +8,6 @@ import ( var log = logging.Init() type WidgetUpdater interface { - SetMeta(string, string) + SetMeta(models.Meta) SetMetrics(models.Metrics) } diff --git a/cwidgets/single/main.go b/cwidgets/single/main.go index 8140b53..6f7b02c 100644 --- a/cwidgets/single/main.go +++ b/cwidgets/single/main.go @@ -55,11 +55,13 @@ func (e *Single) Down() { } func (e *Single) SetWidth(w int) { e.Width = w } -func (e *Single) SetMeta(k, v string) { - if k == "[ENV-VAR]" { - e.Env.Set(k, v) - } else { - e.Info.Set(k, v) +func (e *Single) SetMeta(m models.Meta) { + for k, v := range m { + if k == "[ENV-VAR]" { + e.Env.Set(k, v) + } else { + e.Info.Set(k, v) + } } } diff --git a/models/main.go b/models/main.go index feb23ce..dfbb30e 100644 --- a/models/main.go +++ b/models/main.go @@ -7,6 +7,17 @@ type Log struct { Message string } +type Meta map[string]string + +func NewMeta() Meta { return make(Meta) } + +func (m Meta) Get(k string) string { + if s, ok := m[k]; ok { + return s + } + return "" +} + type Metrics struct { CPUUtil int NetTx int64