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>
| ... | ... |
@@ -170,6 +170,9 @@ type Stats struct {
|
| 170 | 170 |
type StatsJSON struct {
|
| 171 | 171 |
Stats |
| 172 | 172 |
|
| 173 |
+ Name string `json:"name,omitempty"` |
|
| 174 |
+ ID string `json:"id,omitempty"` |
|
| 175 |
+ |
|
| 173 | 176 |
// Networks request version >=1.21 |
| 174 | 177 |
Networks map[string]NetworkStats `json:"networks,omitempty"` |
| 175 | 178 |
} |
| ... | ... |
@@ -29,7 +29,7 @@ var daemonOSType string |
| 29 | 29 |
func (s *stats) add(cs *formatter.ContainerStats) bool {
|
| 30 | 30 |
s.mu.Lock() |
| 31 | 31 |
defer s.mu.Unlock() |
| 32 |
- if _, exists := s.isKnownContainer(cs.Name); !exists {
|
|
| 32 |
+ if _, exists := s.isKnownContainer(cs.Container); !exists {
|
|
| 33 | 33 |
s.cs = append(s.cs, cs) |
| 34 | 34 |
return true |
| 35 | 35 |
} |
| ... | ... |
@@ -46,7 +46,7 @@ func (s *stats) remove(id string) {
|
| 46 | 46 |
|
| 47 | 47 |
func (s *stats) isKnownContainer(cid string) (int, bool) {
|
| 48 | 48 |
for i, c := range s.cs {
|
| 49 |
- if c.Name == cid {
|
|
| 49 |
+ if c.Container == cid {
|
|
| 50 | 50 |
return i, true |
| 51 | 51 |
} |
| 52 | 52 |
} |
| ... | ... |
@@ -54,7 +54,7 @@ func (s *stats) isKnownContainer(cid string) (int, bool) {
|
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 | 56 |
func collect(s *formatter.ContainerStats, ctx context.Context, cli client.APIClient, streamStats bool, waitFirst *sync.WaitGroup) {
|
| 57 |
- logrus.Debugf("collecting stats for %s", s.Name)
|
|
| 57 |
+ logrus.Debugf("collecting stats for %s", s.Container)
|
|
| 58 | 58 |
var ( |
| 59 | 59 |
getFirst bool |
| 60 | 60 |
previousCPU uint64 |
| ... | ... |
@@ -70,7 +70,7 @@ func collect(s *formatter.ContainerStats, ctx context.Context, cli client.APICli |
| 70 | 70 |
} |
| 71 | 71 |
}() |
| 72 | 72 |
|
| 73 |
- response, err := cli.ContainerStats(ctx, s.Name, streamStats) |
|
| 73 |
+ response, err := cli.ContainerStats(ctx, s.Container, streamStats) |
|
| 74 | 74 |
if err != nil {
|
| 75 | 75 |
s.SetError(err) |
| 76 | 76 |
return |
| ... | ... |
@@ -125,6 +125,8 @@ func collect(s *formatter.ContainerStats, ctx context.Context, cli client.APICli |
| 125 | 125 |
} |
| 126 | 126 |
netRx, netTx := calculateNetwork(v.Networks) |
| 127 | 127 |
s.SetStatistics(formatter.StatsEntry{
|
| 128 |
+ Name: v.Name, |
|
| 129 |
+ ID: v.ID, |
|
| 128 | 130 |
CPUPercentage: cpuPercent, |
| 129 | 131 |
Memory: mem, |
| 130 | 132 |
MemoryPercentage: memPerc, |
| ... | ... |
@@ -24,7 +24,9 @@ const ( |
| 24 | 24 |
|
| 25 | 25 |
// StatsEntry represents represents the statistics data collected from a container |
| 26 | 26 |
type StatsEntry struct {
|
| 27 |
+ Container string |
|
| 27 | 28 |
Name string |
| 29 |
+ ID string |
|
| 28 | 30 |
CPUPercentage float64 |
| 29 | 31 |
Memory float64 // On Windows this is the private working set |
| 30 | 32 |
MemoryLimit float64 // Not used on Windows |
| ... | ... |
@@ -85,7 +87,7 @@ func (cs *ContainerStats) SetError(err error) {
|
| 85 | 85 |
func (cs *ContainerStats) SetStatistics(s StatsEntry) {
|
| 86 | 86 |
cs.mutex.Lock() |
| 87 | 87 |
defer cs.mutex.Unlock() |
| 88 |
- s.Name = cs.Name |
|
| 88 |
+ s.Container = cs.Container |
|
| 89 | 89 |
s.OSType = cs.OSType |
| 90 | 90 |
cs.StatsEntry = s |
| 91 | 91 |
} |
| ... | ... |
@@ -109,9 +111,9 @@ func NewStatsFormat(source, osType string) Format {
|
| 109 | 109 |
} |
| 110 | 110 |
|
| 111 | 111 |
// NewContainerStats returns a new ContainerStats entity and sets in it the given name |
| 112 |
-func NewContainerStats(name, osType string) *ContainerStats {
|
|
| 112 |
+func NewContainerStats(container, osType string) *ContainerStats {
|
|
| 113 | 113 |
return &ContainerStats{
|
| 114 |
- StatsEntry: StatsEntry{Name: name, OSType: osType},
|
|
| 114 |
+ StatsEntry: StatsEntry{Container: container, OSType: osType},
|
|
| 115 | 115 |
} |
| 116 | 116 |
} |
| 117 | 117 |
|
| ... | ... |
@@ -138,7 +140,18 @@ type containerStatsContext struct {
|
| 138 | 138 |
|
| 139 | 139 |
func (c *containerStatsContext) Container() string {
|
| 140 | 140 |
c.AddHeader(containerHeader) |
| 141 |
- return c.s.Name |
|
| 141 |
+ return c.s.Container |
|
| 142 |
+} |
|
| 143 |
+ |
|
| 144 |
+func (c *containerStatsContext) Name() string {
|
|
| 145 |
+ c.AddHeader(nameHeader) |
|
| 146 |
+ name := c.s.Name[1:] |
|
| 147 |
+ return name |
|
| 148 |
+} |
|
| 149 |
+ |
|
| 150 |
+func (c *containerStatsContext) ID() string {
|
|
| 151 |
+ c.AddHeader(containerIDHeader) |
|
| 152 |
+ return c.s.ID |
|
| 142 | 153 |
} |
| 143 | 154 |
|
| 144 | 155 |
func (c *containerStatsContext) CPUPerc() string {
|
| ... | ... |
@@ -18,7 +18,7 @@ func TestContainerStatsContext(t *testing.T) {
|
| 18 | 18 |
expHeader string |
| 19 | 19 |
call func() string |
| 20 | 20 |
}{
|
| 21 |
- {StatsEntry{Name: containerID}, containerID, containerHeader, ctx.Container},
|
|
| 21 |
+ {StatsEntry{Container: containerID}, containerID, containerHeader, ctx.Container},
|
|
| 22 | 22 |
{StatsEntry{CPUPercentage: 5.5}, "5.50%", cpuPercHeader, ctx.CPUPerc},
|
| 23 | 23 |
{StatsEntry{CPUPercentage: 5.5, IsInvalid: true}, "--", cpuPercHeader, ctx.CPUPerc},
|
| 24 | 24 |
{StatsEntry{NetworkRx: 0.31, NetworkTx: 12.3}, "0.31 B / 12.3 B", netIOHeader, ctx.NetIO},
|
| ... | ... |
@@ -82,7 +82,7 @@ container2 -- |
| 82 | 82 |
for _, te := range tt {
|
| 83 | 83 |
stats := []StatsEntry{
|
| 84 | 84 |
{
|
| 85 |
- Name: "container1", |
|
| 85 |
+ Container: "container1", |
|
| 86 | 86 |
CPUPercentage: 20, |
| 87 | 87 |
Memory: 20, |
| 88 | 88 |
MemoryLimit: 20, |
| ... | ... |
@@ -96,7 +96,7 @@ container2 -- |
| 96 | 96 |
OSType: "linux", |
| 97 | 97 |
}, |
| 98 | 98 |
{
|
| 99 |
- Name: "container2", |
|
| 99 |
+ Container: "container2", |
|
| 100 | 100 |
CPUPercentage: 30, |
| 101 | 101 |
Memory: 30, |
| 102 | 102 |
MemoryLimit: 30, |
| ... | ... |
@@ -150,7 +150,7 @@ container2 -- -- |
| 150 | 150 |
for _, te := range tt {
|
| 151 | 151 |
stats := []StatsEntry{
|
| 152 | 152 |
{
|
| 153 |
- Name: "container1", |
|
| 153 |
+ Container: "container1", |
|
| 154 | 154 |
CPUPercentage: 20, |
| 155 | 155 |
Memory: 20, |
| 156 | 156 |
MemoryLimit: 20, |
| ... | ... |
@@ -164,7 +164,7 @@ container2 -- -- |
| 164 | 164 |
OSType: "windows", |
| 165 | 165 |
}, |
| 166 | 166 |
{
|
| 167 |
- Name: "container2", |
|
| 167 |
+ Container: "container2", |
|
| 168 | 168 |
CPUPercentage: 30, |
| 169 | 169 |
Memory: 30, |
| 170 | 170 |
MemoryLimit: 30, |
| ... | ... |
@@ -44,6 +44,8 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c |
| 44 | 44 |
var preRead time.Time |
| 45 | 45 |
getStatJSON := func(v interface{}) *types.StatsJSON {
|
| 46 | 46 |
ss := v.(types.StatsJSON) |
| 47 |
+ ss.Name = container.Name |
|
| 48 |
+ ss.ID = container.ID |
|
| 47 | 49 |
ss.PreCPUStats = preCPUStats |
| 48 | 50 |
ss.PreRead = preRead |
| 49 | 51 |
preCPUStats = ss.CPUStats |