diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index a7ba9c37b2..ff9eadf75b 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -1165,6 +1165,9 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) { } stats, err := daemon.containerd.Stats(c.ID) if err != nil { + if strings.Contains(err.Error(), "container not found") { + return nil, errNotFound{c.ID} + } return nil, err } s := &types.StatsJSON{} diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index bb9c85b80e..798ba39971 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -525,6 +525,9 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) { // Obtain the stats from HCS via libcontainerd stats, err := daemon.containerd.Stats(c.ID) if err != nil { + if strings.Contains(err.Error(), "container not found") { + return nil, errNotFound{c.ID} + } return nil, err } diff --git a/daemon/errors.go b/daemon/errors.go index 96c30df2ea..5050f87e4c 100644 --- a/daemon/errors.go +++ b/daemon/errors.go @@ -39,3 +39,15 @@ func errExecPaused(id string) error { err := fmt.Errorf("Container %s is paused, unpause the container before exec", id) return errors.NewRequestConflictError(err) } + +type errNotFound struct { + containerID string +} + +func (e errNotFound) Error() string { + return fmt.Sprintf("Container %s is not found", e.containerID) +} + +func (e errNotFound) ContainerNotFound() bool { + return true +} diff --git a/daemon/stats/collector.go b/daemon/stats/collector.go index 71bcff446e..0520efa238 100644 --- a/daemon/stats/collector.go +++ b/daemon/stats/collector.go @@ -88,24 +88,25 @@ func (s *Collector) Run() { for _, pair := range pairs { stats, err := s.supervisor.GetContainerStats(pair.container) - 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 + switch err.(type) { + case nil: + // FIXME: move to containerd on Linux (not Windows) + stats.CPUStats.SystemUsage = systemUsage + stats.CPUStats.OnlineCPUs = onlineCPUs + + pair.publisher.Publish(*stats) + + case notRunningErr, notFoundErr: + // publish empty stats containing only name and ID if not running or not found pair.publisher.Publish(types.StatsJSON{ Name: pair.container.Name, ID: pair.container.ID, }) - continue - } - // FIXME: move to containerd on Linux (not Windows) - stats.CPUStats.SystemUsage = systemUsage - stats.CPUStats.OnlineCPUs = onlineCPUs - pair.publisher.Publish(*stats) + default: + logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err) + } } } } @@ -114,3 +115,8 @@ type notRunningErr interface { error ContainerIsRunning() bool } + +type notFoundErr interface { + error + ContainerNotFound() bool +}