diff --git a/daemon/stats.go b/daemon/stats.go index d5aa43d3d9..926f32efdb 100644 --- a/daemon/stats.go +++ b/daemon/stats.go @@ -33,7 +33,9 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c // If the container is either not running or restarting and requires no stream, return an empty stats. if (!container.IsRunning() || container.IsRestarting()) && !config.Stream { - return json.NewEncoder(config.OutStream).Encode(&types.Stats{}) + return json.NewEncoder(config.OutStream).Encode(&types.StatsJSON{ + Name: container.Name, + ID: container.ID}) } outStream := config.OutStream diff --git a/daemon/stats/collector.go b/daemon/stats/collector.go index e7eec7631e..4627154024 100644 --- a/daemon/stats/collector.go +++ b/daemon/stats/collector.go @@ -6,6 +6,7 @@ import ( "time" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types" "github.com/docker/docker/container" "github.com/docker/docker/pkg/pubsub" ) @@ -84,7 +85,14 @@ func (s *Collector) Run() { if err != nil { if _, ok := err.(notRunningErr); !ok { logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err) + continue } + + // publish empty stats containing only name and ID if not running + pair.publisher.Publish(types.StatsJSON{ + Name: pair.container.Name, + ID: pair.container.ID, + }) continue } // FIXME: move to containerd on Linux (not Windows) diff --git a/integration-cli/docker_cli_stats_test.go b/integration-cli/docker_cli_stats_test.go index 56355a5433..d1dbd73320 100644 --- a/integration-cli/docker_cli_stats_test.go +++ b/integration-cli/docker_cli_stats_test.go @@ -157,3 +157,22 @@ func (s *DockerSuite) TestStatsAllNewContainersAdded(c *check.C) { // ignore, done } } + +func (s *DockerSuite) TestStatsFormatAll(c *check.C) { + // Windows does not support stats + testRequires(c, DaemonIsLinux) + + dockerCmd(c, "run", "-d", "--name=RunningOne", "busybox", "top") + c.Assert(waitRun("RunningOne"), check.IsNil) + dockerCmd(c, "run", "-d", "--name=ExitedOne", "busybox", "top") + dockerCmd(c, "stop", "ExitedOne") + c.Assert(waitExited("ExitedOne", 5*time.Second), check.IsNil) + + out, _ := dockerCmd(c, "stats", "--no-stream", "--format", "{{.Name}}") + c.Assert(out, checker.Contains, "RunningOne") + c.Assert(out, checker.Not(checker.Contains), "ExitedOne") + + out, _ = dockerCmd(c, "stats", "--all", "--no-stream", "--format", "{{.Name}}") + c.Assert(out, checker.Contains, "RunningOne") + c.Assert(out, checker.Contains, "ExitedOne") +}