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 <vincent@sbr.pm>
This commit is contained in:
Vincent Demeester 2016-11-03 07:20:46 +01:00
parent e279ecacc5
commit 07f77b78ea
3 changed files with 28 additions and 13 deletions

View File

@ -29,7 +29,7 @@ var daemonOSType string
func (s *stats) add(cs *formatter.ContainerStats) bool { func (s *stats) add(cs *formatter.ContainerStats) bool {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
if _, exists := s.isKnownContainer(cs.Name); !exists { if _, exists := s.isKnownContainer(cs.Container); !exists {
s.cs = append(s.cs, cs) s.cs = append(s.cs, cs)
return true return true
} }
@ -46,7 +46,7 @@ func (s *stats) remove(id string) {
func (s *stats) isKnownContainer(cid string) (int, bool) { func (s *stats) isKnownContainer(cid string) (int, bool) {
for i, c := range s.cs { for i, c := range s.cs {
if c.Name == cid { if c.Container == cid {
return i, true 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) { 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 ( var (
getFirst bool getFirst bool
previousCPU uint64 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 { if err != nil {
s.SetError(err) s.SetError(err)
return return
@ -125,6 +125,8 @@ func collect(s *formatter.ContainerStats, ctx context.Context, cli client.APICli
} }
netRx, netTx := calculateNetwork(v.Networks) netRx, netTx := calculateNetwork(v.Networks)
s.SetStatistics(formatter.StatsEntry{ s.SetStatistics(formatter.StatsEntry{
Name: v.Name,
ID: v.ID,
CPUPercentage: cpuPercent, CPUPercentage: cpuPercent,
Memory: mem, Memory: mem,
MemoryPercentage: memPerc, MemoryPercentage: memPerc,

View File

@ -24,7 +24,9 @@ const (
// StatsEntry represents represents the statistics data collected from a container // StatsEntry represents represents the statistics data collected from a container
type StatsEntry struct { type StatsEntry struct {
Container string
Name string Name string
ID string
CPUPercentage float64 CPUPercentage float64
Memory float64 // On Windows this is the private working set Memory float64 // On Windows this is the private working set
MemoryLimit float64 // Not used on Windows MemoryLimit float64 // Not used on Windows
@ -85,7 +87,7 @@ func (cs *ContainerStats) SetError(err error) {
func (cs *ContainerStats) SetStatistics(s StatsEntry) { func (cs *ContainerStats) SetStatistics(s StatsEntry) {
cs.mutex.Lock() cs.mutex.Lock()
defer cs.mutex.Unlock() defer cs.mutex.Unlock()
s.Name = cs.Name s.Container = cs.Container
s.OSType = cs.OSType s.OSType = cs.OSType
cs.StatsEntry = s 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 // 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{ 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 { func (c *containerStatsContext) Container() string {
c.AddHeader(containerHeader) 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 { func (c *containerStatsContext) CPUPerc() string {

View File

@ -18,7 +18,7 @@ func TestContainerStatsContext(t *testing.T) {
expHeader string expHeader string
call func() 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}, "5.50%", cpuPercHeader, ctx.CPUPerc},
{StatsEntry{CPUPercentage: 5.5, IsInvalid: true}, "--", 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}, {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 { for _, te := range tt {
stats := []StatsEntry{ stats := []StatsEntry{
{ {
Name: "container1", Container: "container1",
CPUPercentage: 20, CPUPercentage: 20,
Memory: 20, Memory: 20,
MemoryLimit: 20, MemoryLimit: 20,
@ -96,7 +96,7 @@ container2 --
OSType: "linux", OSType: "linux",
}, },
{ {
Name: "container2", Container: "container2",
CPUPercentage: 30, CPUPercentage: 30,
Memory: 30, Memory: 30,
MemoryLimit: 30, MemoryLimit: 30,
@ -150,7 +150,7 @@ container2 -- --
for _, te := range tt { for _, te := range tt {
stats := []StatsEntry{ stats := []StatsEntry{
{ {
Name: "container1", Container: "container1",
CPUPercentage: 20, CPUPercentage: 20,
Memory: 20, Memory: 20,
MemoryLimit: 20, MemoryLimit: 20,
@ -164,7 +164,7 @@ container2 -- --
OSType: "windows", OSType: "windows",
}, },
{ {
Name: "container2", Container: "container2",
CPUPercentage: 30, CPUPercentage: 30,
Memory: 30, Memory: 30,
MemoryLimit: 30, MemoryLimit: 30,