refactor compact widgets into subpackage

This commit is contained in:
Bradley Cicenas 2017-01-06 11:51:11 +00:00
parent 3ec384414d
commit 87d5ba447b
9 changed files with 132 additions and 162 deletions

View File

@ -1,6 +1,9 @@
package main
import (
"strings"
"github.com/bcicen/ctop/widgets"
"github.com/fsouza/go-dockerclient"
)
@ -9,10 +12,23 @@ type Container struct {
name string
done chan bool
stats chan *docker.Stats
widgets *Widgets
widgets *widgets.Compact
reader *StatReader
}
func NewContainer(c docker.APIContainers) *Container {
id := c.ID[:12]
name := strings.Replace(c.Names[0], "/", "", 1) // use primary container name
return &Container{
id: id,
name: name,
done: make(chan bool),
stats: make(chan *docker.Stats),
widgets: widgets.NewCompact(id, name),
reader: &StatReader{},
}
}
func (c *Container) Collect(client *docker.Client) {
go func() {
@ -28,7 +44,7 @@ func (c *Container) Collect(client *docker.Client) {
go func() {
for s := range c.stats {
c.reader.Read(s)
c.widgets.cpu.Set(c.reader.CPUUtil)
c.widgets.SetCPU(c.reader.CPUUtil)
c.widgets.SetMem(c.reader.MemUsage, c.reader.MemLimit)
c.widgets.SetNet(c.reader.NetRx, c.reader.NetTx)
}

View File

@ -1,8 +1,6 @@
package main
import (
"strings"
"github.com/fsouza/go-dockerclient"
)
@ -35,6 +33,7 @@ type ContainerMap struct {
}
func (cm *ContainerMap) Refresh() {
var id string
opts := docker.ListContainersOptions{
Filters: filters,
}
@ -43,8 +42,10 @@ func (cm *ContainerMap) Refresh() {
panic(err)
}
for _, c := range containers {
if _, ok := cm.containers[c.ID[:12]]; ok == false {
cm.Add(c)
id = c.ID[:12]
if _, ok := cm.containers[id]; ok == false {
cm.containers[id] = NewContainer(c)
cm.containers[id].Collect(cm.client)
}
}
}
@ -54,20 +55,6 @@ func (cm *ContainerMap) Len() uint {
return uint(len(cm.containers))
}
func (cm *ContainerMap) Add(c docker.APIContainers) {
id := c.ID[:12]
name := strings.Replace(c.Names[0], "/", "", 1) // use primary container name
cm.containers[id] = &Container{
id: id,
name: name,
done: make(chan bool),
stats: make(chan *docker.Stats),
widgets: NewWidgets(id, name),
reader: &StatReader{},
}
cm.containers[id].Collect(cm.client)
}
// Get a single container, by ID
func (cm *ContainerMap) Get(id string) *Container {
return cm.containers[id]

10
grid.go
View File

@ -54,11 +54,11 @@ func (g *Grid) cursorDown() {
func (g *Grid) redrawCursor() {
for _, c := range g.containers {
if c.id == g.cursorID {
c.widgets.name.TextFgColor = ui.ColorDefault
c.widgets.name.TextBgColor = ui.ColorWhite
c.widgets.Name.TextFgColor = ui.ColorDefault
c.widgets.Name.TextBgColor = ui.ColorWhite
} else {
c.widgets.name.TextFgColor = ui.ColorWhite
c.widgets.name.TextBgColor = ui.ColorDefault
c.widgets.Name.TextFgColor = ui.ColorWhite
c.widgets.Name.TextBgColor = ui.ColorDefault
}
ui.Render(ui.Body)
}
@ -71,7 +71,7 @@ func (g *Grid) redrawRows() {
// build layout
ui.Body.AddRows(header())
for _, c := range g.containers {
ui.Body.AddRows(c.widgets.MakeRow())
ui.Body.AddRows(c.widgets.Row())
}
ui.Body.Align()

View File

@ -5,7 +5,7 @@ import (
)
type StatReader struct {
CPUUtil int
CPUUtil float64
NetTx int64
NetRx int64
MemUsage int64
@ -28,7 +28,7 @@ func (s *StatReader) ReadCPU(stats *docker.Stats) {
cpudiff := total - s.lastCpu
syscpudiff := system - s.lastSysCpu
s.CPUUtil = round((cpudiff / syscpudiff * 100) * ncpus)
s.CPUUtil = (cpudiff / syscpudiff * 100) * ncpus
s.lastCpu = total
s.lastSysCpu = system
}

33
util.go
View File

@ -1,33 +0,0 @@
package main
import (
"fmt"
"math"
"strconv"
)
const (
kb = 1024
mb = kb * 1024
gb = mb * 1024
)
func byteFormat(n int64) string {
if n < kb {
return fmt.Sprintf("%sB", strconv.FormatInt(n, 10))
}
if n < mb {
n = n / kb
return fmt.Sprintf("%sK", strconv.FormatInt(n, 10))
}
if n < gb {
n = n / mb
return fmt.Sprintf("%sM", strconv.FormatInt(n, 10))
}
n = n / gb
return fmt.Sprintf("%sG", strconv.FormatInt(n, 10))
}
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}

View File

@ -1,76 +0,0 @@
package main
import (
"fmt"
"github.com/bcicen/ctop/widgets"
ui "github.com/gizak/termui"
)
type Widgets struct {
cid *ui.Par
net *ui.Par
name *ui.Par
cpu *widgets.CPU
memory *ui.Gauge
}
func (w *Widgets) MakeRow() *ui.Row {
return ui.NewRow(
ui.NewCol(2, 0, w.name),
ui.NewCol(2, 0, w.cid),
ui.NewCol(2, 0, w.cpu),
ui.NewCol(2, 0, w.memory),
ui.NewCol(2, 0, w.net),
)
}
func (w *Widgets) SetNet(rx int64, tx int64) {
w.net.Text = fmt.Sprintf("%s / %s", byteFormat(rx), byteFormat(tx))
}
func (w *Widgets) SetMem(val int64, limit int64) {
percent := round((float64(val) / float64(limit)) * 100)
w.memory.Label = fmt.Sprintf("%s / %s", byteFormat(val), byteFormat(limit))
if percent < 5 {
percent = 5
w.memory.BarColor = ui.ColorBlack
} else {
w.memory.BarColor = ui.ColorGreen
}
w.memory.Percent = percent
}
func NewWidgets(id string, names string) *Widgets {
cid := ui.NewPar(id)
cid.Border = false
cid.Height = 1
cid.Width = 20
cid.TextFgColor = ui.ColorWhite
name := ui.NewPar(names)
name.Border = false
name.Height = 1
name.Width = 20
name.TextFgColor = ui.ColorWhite
net := ui.NewPar("-")
net.Border = false
net.Height = 1
net.Width = 20
net.TextFgColor = ui.ColorWhite
return &Widgets{cid, net, name, widgets.NewCPU(), mkGauge()}
}
func mkGauge() *ui.Gauge {
g := ui.NewGauge()
g.Height = 1
g.Border = false
g.Percent = 0
g.PaddingBottom = 0
g.BarColor = ui.ColorGreen
g.Label = "-"
return g
}

63
widgets/compact.go Normal file
View File

@ -0,0 +1,63 @@
package widgets
import (
"fmt"
"strconv"
ui "github.com/gizak/termui"
)
type Compact struct {
Cid *ui.Par
Net *ui.Par
Name *ui.Par
Cpu *ui.Gauge
Memory *ui.Gauge
}
func NewCompact(id string, name string) *Compact {
return &Compact{
Cid: compactPar(id),
Net: compactPar("-"),
Name: compactPar(name),
Cpu: mkGauge(),
Memory: mkGauge(),
}
}
func (w *Compact) Row() *ui.Row {
return ui.NewRow(
ui.NewCol(2, 0, w.Name),
ui.NewCol(2, 0, w.Cid),
ui.NewCol(2, 0, w.Cpu),
ui.NewCol(2, 0, w.Memory),
ui.NewCol(2, 0, w.Net),
)
}
func (w *Compact) SetCPU(val float64) {
intVal := round(val)
w.Cpu.BarColor = colorScale(intVal)
w.Cpu.Label = fmt.Sprintf("%s%%", strconv.Itoa(intVal))
if intVal < 5 {
intVal = 5
w.Cpu.BarColor = ui.ColorBlack
}
w.Cpu.Percent = intVal
}
func (w *Compact) SetNet(rx int64, tx int64) {
w.Net.Text = fmt.Sprintf("%s / %s", byteFormat(rx), byteFormat(tx))
}
func (w *Compact) SetMem(val int64, limit int64) {
percent := round((float64(val) / float64(limit)) * 100)
w.Memory.Label = fmt.Sprintf("%s / %s", byteFormat(val), byteFormat(limit))
if percent < 5 {
percent = 5
w.Memory.BarColor = ui.ColorBlack
} else {
w.Memory.BarColor = ui.ColorGreen
}
w.Memory.Percent = percent
}

View File

@ -1,26 +0,0 @@
package widgets
import (
"fmt"
"strconv"
ui "github.com/gizak/termui"
)
type CPU struct {
*ui.Gauge
}
func NewCPU() *CPU {
return &CPU{mkGauge()}
}
func (c *CPU) Set(val int) {
c.BarColor = colorScale(val)
c.Label = fmt.Sprintf("%s%%", strconv.Itoa(val))
if val < 5 {
val = 5
c.BarColor = ui.ColorBlack
}
c.Percent = val
}

View File

@ -1,9 +1,48 @@
package widgets
import (
"fmt"
"math"
"strconv"
ui "github.com/gizak/termui"
)
const (
kb = 1024
mb = kb * 1024
gb = mb * 1024
)
func byteFormat(n int64) string {
if n < kb {
return fmt.Sprintf("%sB", strconv.FormatInt(n, 10))
}
if n < mb {
n = n / kb
return fmt.Sprintf("%sK", strconv.FormatInt(n, 10))
}
if n < gb {
n = n / mb
return fmt.Sprintf("%sM", strconv.FormatInt(n, 10))
}
n = n / gb
return fmt.Sprintf("%sG", strconv.FormatInt(n, 10))
}
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}
func compactPar(s string) *ui.Par {
p := ui.NewPar(s)
p.Border = false
p.Height = 1
p.Width = 20
p.TextFgColor = ui.ColorWhite
return p
}
func mkGauge() *ui.Gauge {
g := ui.NewGauge()
g.Height = 1