mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
initial refactor of all column widgets to standard interface
This commit is contained in:
parent
8fcd14e097
commit
918ccdbe39
@ -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) {
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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)
|
||||
|
@ -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) {}
|
||||
|
@ -8,6 +8,6 @@ import (
|
||||
var log = logging.Init()
|
||||
|
||||
type WidgetUpdater interface {
|
||||
SetMeta(string, string)
|
||||
SetMeta(models.Meta)
|
||||
SetMetrics(models.Metrics)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user