From 07f77b78eaf1474057142f4c9e63de04a57b9ab0 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Thu, 3 Nov 2016 07:20:46 +0100 Subject: [PATCH] Add support for Names and ID in stats format This adds support to display names or id of container instead of what was provided in the request. This keeps the default behavior (`docker stats byname` will display `byname` in the `CONTAINER` colmun and `docker stats byid` will display the id in the `CONTAINER` column) but adds two new format directive. Signed-off-by: Vincent Demeester --- command/container/stats_helpers.go | 10 ++++++---- command/formatter/stats.go | 21 +++++++++++++++++---- command/formatter/stats_test.go | 10 +++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/command/container/stats_helpers.go b/command/container/stats_helpers.go index 32ad84841b..8bc537ad3c 100644 --- a/command/container/stats_helpers.go +++ b/command/container/stats_helpers.go @@ -29,7 +29,7 @@ var daemonOSType string func (s *stats) add(cs *formatter.ContainerStats) bool { s.mu.Lock() defer s.mu.Unlock() - if _, exists := s.isKnownContainer(cs.Name); !exists { + if _, exists := s.isKnownContainer(cs.Container); !exists { s.cs = append(s.cs, cs) return true } @@ -46,7 +46,7 @@ func (s *stats) remove(id string) { func (s *stats) isKnownContainer(cid string) (int, bool) { for i, c := range s.cs { - if c.Name == cid { + if c.Container == cid { return i, true } } @@ -54,7 +54,7 @@ func (s *stats) isKnownContainer(cid string) (int, bool) { } func collect(s *formatter.ContainerStats, ctx context.Context, cli client.APIClient, streamStats bool, waitFirst *sync.WaitGroup) { - logrus.Debugf("collecting stats for %s", s.Name) + logrus.Debugf("collecting stats for %s", s.Container) var ( getFirst bool previousCPU uint64 @@ -70,7 +70,7 @@ func collect(s *formatter.ContainerStats, ctx context.Context, cli client.APICli } }() - response, err := cli.ContainerStats(ctx, s.Name, streamStats) + response, err := cli.ContainerStats(ctx, s.Container, streamStats) if err != nil { s.SetError(err) return @@ -125,6 +125,8 @@ func collect(s *formatter.ContainerStats, ctx context.Context, cli client.APICli } netRx, netTx := calculateNetwork(v.Networks) s.SetStatistics(formatter.StatsEntry{ + Name: v.Name, + ID: v.ID, CPUPercentage: cpuPercent, Memory: mem, MemoryPercentage: memPerc, diff --git a/command/formatter/stats.go b/command/formatter/stats.go index b2c972251f..7997f996d8 100644 --- a/command/formatter/stats.go +++ b/command/formatter/stats.go @@ -24,7 +24,9 @@ const ( // StatsEntry represents represents the statistics data collected from a container type StatsEntry struct { + Container string Name string + ID string CPUPercentage float64 Memory float64 // On Windows this is the private working set MemoryLimit float64 // Not used on Windows @@ -85,7 +87,7 @@ func (cs *ContainerStats) SetError(err error) { func (cs *ContainerStats) SetStatistics(s StatsEntry) { cs.mutex.Lock() defer cs.mutex.Unlock() - s.Name = cs.Name + s.Container = cs.Container s.OSType = cs.OSType cs.StatsEntry = s } @@ -109,9 +111,9 @@ func NewStatsFormat(source, osType string) Format { } // NewContainerStats returns a new ContainerStats entity and sets in it the given name -func NewContainerStats(name, osType string) *ContainerStats { +func NewContainerStats(container, osType string) *ContainerStats { return &ContainerStats{ - StatsEntry: StatsEntry{Name: name, OSType: osType}, + StatsEntry: StatsEntry{Container: container, OSType: osType}, } } @@ -138,7 +140,18 @@ type containerStatsContext struct { func (c *containerStatsContext) Container() string { c.AddHeader(containerHeader) - return c.s.Name + return c.s.Container +} + +func (c *containerStatsContext) Name() string { + c.AddHeader(nameHeader) + name := c.s.Name[1:] + return name +} + +func (c *containerStatsContext) ID() string { + c.AddHeader(containerIDHeader) + return c.s.ID } func (c *containerStatsContext) CPUPerc() string { diff --git a/command/formatter/stats_test.go b/command/formatter/stats_test.go index f1f449e71a..d5a17cc70e 100644 --- a/command/formatter/stats_test.go +++ b/command/formatter/stats_test.go @@ -18,7 +18,7 @@ func TestContainerStatsContext(t *testing.T) { expHeader string call func() string }{ - {StatsEntry{Name: containerID}, containerID, containerHeader, ctx.Container}, + {StatsEntry{Container: containerID}, containerID, containerHeader, ctx.Container}, {StatsEntry{CPUPercentage: 5.5}, "5.50%", cpuPercHeader, ctx.CPUPerc}, {StatsEntry{CPUPercentage: 5.5, IsInvalid: true}, "--", cpuPercHeader, ctx.CPUPerc}, {StatsEntry{NetworkRx: 0.31, NetworkTx: 12.3}, "0.31 B / 12.3 B", netIOHeader, ctx.NetIO}, @@ -82,7 +82,7 @@ container2 -- for _, te := range tt { stats := []StatsEntry{ { - Name: "container1", + Container: "container1", CPUPercentage: 20, Memory: 20, MemoryLimit: 20, @@ -96,7 +96,7 @@ container2 -- OSType: "linux", }, { - Name: "container2", + Container: "container2", CPUPercentage: 30, Memory: 30, MemoryLimit: 30, @@ -150,7 +150,7 @@ container2 -- -- for _, te := range tt { stats := []StatsEntry{ { - Name: "container1", + Container: "container1", CPUPercentage: 20, Memory: 20, MemoryLimit: 20, @@ -164,7 +164,7 @@ container2 -- -- OSType: "windows", }, { - Name: "container2", + Container: "container2", CPUPercentage: 30, Memory: 30, MemoryLimit: 30,