소스 검색

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>
Vincent Demeester 8 년 전
부모
커밋
ef915fd036
5개의 변경된 파일33개의 추가작업 그리고 13개의 파일을 삭제
  1. 3 0
      api/types/stats.go
  2. 6 4
      cli/command/container/stats_helpers.go
  3. 17 4
      cli/command/formatter/stats.go
  4. 5 5
      cli/command/formatter/stats_test.go
  5. 2 0
      daemon/stats.go

+ 3 - 0
api/types/stats.go

@@ -170,6 +170,9 @@ type Stats struct {
 type StatsJSON struct {
 	Stats
 
+	Name string `json:"name,omitempty"`
+	ID   string `json:"id,omitempty"`
+
 	// Networks request version >=1.21
 	Networks map[string]NetworkStats `json:"networks,omitempty"`
 }

+ 6 - 4
cli/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,

+ 17 - 4
cli/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 {

+ 5 - 5
cli/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,

+ 2 - 0
daemon/stats.go

@@ -44,6 +44,8 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
 	var preRead time.Time
 	getStatJSON := func(v interface{}) *types.StatsJSON {
 		ss := v.(types.StatsJSON)
+		ss.Name = container.Name
+		ss.ID = container.ID
 		ss.PreCPUStats = preCPUStats
 		ss.PreRead = preRead
 		preCPUStats = ss.CPUStats