Преглед на файлове

Merge pull request #21853 from coolljt0725/fix_stats

Fix docker stats missing mem limit
Vincent Demeester преди 9 години
родител
ревизия
a01f4dc229
променени са 3 файла, в които са добавени 40 реда и са изтрити 0 реда
  1. 5 0
      daemon/daemon_unix.go
  2. 7 0
      daemon/stats_collector_unix.go
  3. 28 0
      integration-cli/docker_api_stats_test.go

+ 5 - 0
daemon/daemon_unix.go

@@ -1101,6 +1101,11 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
 			MaxUsage: mem.MaxUsage,
 			Stats:    cgs.MemoryStats.Stats,
 			Failcnt:  mem.Failcnt,
+			Limit:    mem.Limit,
+		}
+		// if the container does not set memory limit, use the machineMemory
+		if mem.Limit > daemon.statsCollector.machineMemory && daemon.statsCollector.machineMemory > 0 {
+			s.MemoryStats.Limit = daemon.statsCollector.machineMemory
 		}
 		if cgs.PidsStats != nil {
 			s.PidsStats = types.PidsStats{

+ 7 - 0
daemon/stats_collector_unix.go

@@ -14,6 +14,7 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/pubsub"
+	sysinfo "github.com/docker/docker/pkg/system"
 	"github.com/docker/engine-api/types"
 	"github.com/opencontainers/runc/libcontainer/system"
 )
@@ -35,6 +36,11 @@ func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector
 		clockTicksPerSecond: uint64(system.GetClockTicks()),
 		bufReader:           bufio.NewReaderSize(nil, 128),
 	}
+	meminfo, err := sysinfo.ReadMemInfo()
+	if err == nil && meminfo.MemTotal > 0 {
+		s.machineMemory = uint64(meminfo.MemTotal)
+	}
+
 	go s.run()
 	return s
 }
@@ -47,6 +53,7 @@ type statsCollector struct {
 	clockTicksPerSecond uint64
 	publishers          map[*container.Container]*pubsub.Publisher
 	bufReader           *bufio.Reader
+	machineMemory       uint64
 }
 
 // collect registers the container with the collector and adds it to

+ 28 - 0
integration-cli/docker_api_stats_test.go

@@ -227,3 +227,31 @@ func (s *DockerSuite) TestApiStatsContainerNotFound(c *check.C) {
 	c.Assert(err, checker.IsNil)
 	c.Assert(status, checker.Equals, http.StatusNotFound)
 }
+
+func (s *DockerSuite) TestApiStatsContainerGetMemoryLimit(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+
+	resp, body, err := sockRequestRaw("GET", "/info", nil, "application/json")
+	c.Assert(err, checker.IsNil)
+	c.Assert(resp.StatusCode, checker.Equals, http.StatusOK)
+	var info types.Info
+	err = json.NewDecoder(body).Decode(&info)
+	c.Assert(err, checker.IsNil)
+	body.Close()
+
+	// don't set a memory limit, the memory limit should be system memory
+	conName := "foo"
+	dockerCmd(c, "run", "-d", "--name", conName, "busybox", "top")
+	c.Assert(waitRun(conName), checker.IsNil)
+
+	resp, body, err = sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", conName), nil, "")
+	c.Assert(err, checker.IsNil)
+	c.Assert(resp.StatusCode, checker.Equals, http.StatusOK)
+	c.Assert(resp.Header.Get("Content-Type"), checker.Equals, "application/json")
+
+	var v *types.Stats
+	err = json.NewDecoder(body).Decode(&v)
+	c.Assert(err, checker.IsNil)
+	body.Close()
+	c.Assert(fmt.Sprintf("%d", v.MemoryStats.Limit), checker.Equals, fmt.Sprintf("%d", info.MemTotal))
+}