From ee2b63d21d46bd43464f390ee44bafae9aadc2b7 Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Mon, 9 Jan 2017 14:09:26 +0000 Subject: [PATCH] refactor statreader into metricreader, add processed metrics stream --- container.go | 19 +++++++++--------- grid.go | 4 ++-- reader.go | 56 ++++++++++++++++++++++++++++++++++------------------ 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/container.go b/container.go index dc5fcfa..74ba9a8 100644 --- a/container.go +++ b/container.go @@ -11,9 +11,8 @@ type Container struct { id string name string done chan bool - stats chan *docker.Stats widgets widgets.ContainerWidgets - reader *StatReader + reader *MetricsReader } func NewContainer(c docker.APIContainers) *Container { @@ -23,9 +22,8 @@ func NewContainer(c docker.APIContainers) *Container { id: id, name: name, done: make(chan bool), - stats: make(chan *docker.Stats), widgets: widgets.NewCompact(id, name), - reader: &StatReader{}, + reader: NewMetricsReader(), } } @@ -38,10 +36,12 @@ func (c *Container) Collapse() { } func (c *Container) Collect(client *docker.Client) { + stats := make(chan *docker.Stats) + go func() { opts := docker.StatsOptions{ ID: c.id, - Stats: c.stats, + Stats: stats, Stream: true, Done: c.done, } @@ -49,11 +49,10 @@ func (c *Container) Collect(client *docker.Client) { }() go func() { - for s := range c.stats { - c.reader.Read(s) - c.widgets.SetCPU(c.reader.CPUUtil) - c.widgets.SetMem(c.reader.MemUsage, c.reader.MemLimit, c.reader.MemPercent) - c.widgets.SetNet(c.reader.NetRx, c.reader.NetTx) + for metrics := range c.reader.Read(stats) { + c.widgets.SetCPU(metrics.CPUUtil) + c.widgets.SetMem(metrics.MemUsage, metrics.MemLimit, metrics.MemPercent) + c.widgets.SetNet(metrics.NetRx, metrics.NetTx) } }() } diff --git a/grid.go b/grid.go index 91dad05..1f0cfa6 100644 --- a/grid.go +++ b/grid.go @@ -8,8 +8,8 @@ import ( ) type Grid struct { - cursorID string // id of currently selected container - containers []*Container + cursorID string // id of currently selected container + containers []*Container // sorted slice of containers containerMap *ContainerMap header *widgets.CTopHeader } diff --git a/reader.go b/reader.go index 7e39f1c..5479b10 100644 --- a/reader.go +++ b/reader.go @@ -6,47 +6,65 @@ import ( "github.com/fsouza/go-dockerclient" ) -type StatReader struct { +type Metrics struct { CPUUtil int NetTx int64 NetRx int64 MemLimit int64 MemPercent int MemUsage int64 +} + +type MetricsReader struct { + Metrics lastCpu float64 lastSysCpu float64 } -func (s *StatReader) Read(stats *docker.Stats) { - s.ReadCPU(stats) - s.ReadMem(stats) - s.ReadNet(stats) +func NewMetricsReader() *MetricsReader { + return &MetricsReader{} } -func (s *StatReader) ReadCPU(stats *docker.Stats) { +func (m *MetricsReader) Read(statsCh chan *docker.Stats) chan Metrics { + stream := make(chan Metrics) + + go func() { + for s := range statsCh { + m.ReadCPU(s) + m.ReadMem(s) + m.ReadNet(s) + stream <- m.Metrics + } + }() + + return stream +} + +func (m *MetricsReader) ReadCPU(stats *docker.Stats) { ncpus := float64(len(stats.CPUStats.CPUUsage.PercpuUsage)) total := float64(stats.CPUStats.CPUUsage.TotalUsage) system := float64(stats.CPUStats.SystemCPUUsage) - cpudiff := total - s.lastCpu - syscpudiff := system - s.lastSysCpu - s.CPUUtil = round((cpudiff / syscpudiff * 100) * ncpus) - s.lastCpu = total - s.lastSysCpu = system + cpudiff := total - m.lastCpu + syscpudiff := system - m.lastSysCpu + m.CPUUtil = round((cpudiff / syscpudiff * 100) * ncpus) + m.lastCpu = total + m.lastSysCpu = system } -func (s *StatReader) ReadMem(stats *docker.Stats) { - s.MemUsage = int64(stats.MemoryStats.Usage) - s.MemLimit = int64(stats.MemoryStats.Limit) - s.MemPercent = round((float64(s.MemUsage) / float64(s.MemLimit)) * 100) +func (m *MetricsReader) ReadMem(stats *docker.Stats) { + m.MemUsage = int64(stats.MemoryStats.Usage) + m.MemLimit = int64(stats.MemoryStats.Limit) + m.MemPercent = round((float64(m.MemUsage) / float64(m.MemLimit)) * 100) } -func (s *StatReader) ReadNet(stats *docker.Stats) { - s.NetTx, s.NetRx = 0, 0 +func (m *MetricsReader) ReadNet(stats *docker.Stats) { + var rx, tx int64 for _, network := range stats.Networks { - s.NetTx += int64(network.TxBytes) - s.NetRx += int64(network.RxBytes) + rx += int64(network.RxBytes) + tx += int64(network.TxBytes) } + m.NetRx, m.NetTx = rx, tx } func round(num float64) int {