Allow partial success of GetStats().
This should make us more robust in the face of failure (at the cost of making the failures less prominent). We allow GetStats() to return an error and a partial result. We will process the result and report the error. Fixes #306.
This commit is contained in:
parent
01b456c129
commit
86238d0179
@ -82,6 +82,7 @@ func newDockerContainerHandler(
|
||||
usesAufsDriver bool,
|
||||
cgroupSubsystems *containerLibcontainer.CgroupSubsystems,
|
||||
) (container.ContainerHandler, error) {
|
||||
// TODO(vmarmol): Get from factory.
|
||||
fsInfo, err := fs.NewFsInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -299,16 +300,16 @@ func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error
|
||||
func (self *dockerContainerHandler) GetStats() (stats *info.ContainerStats, err error) {
|
||||
state, err := self.readLibcontainerState()
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stats, err = containerLibcontainer.GetStats(self.cgroupPaths, state)
|
||||
if err != nil {
|
||||
return
|
||||
return stats, err
|
||||
}
|
||||
err = self.getFsStats(stats)
|
||||
if err != nil {
|
||||
return
|
||||
return stats, err
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
|
@ -76,6 +76,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu
|
||||
cgroupPaths[key] = path.Join(val, name)
|
||||
}
|
||||
|
||||
// TODO(vmarmol): Get from factory.
|
||||
fsInfo, err := fs.NewFsInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -303,12 +304,12 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
||||
func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
stats, err := libcontainer.GetStats(self.cgroupPaths, &self.libcontainerState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return stats, err
|
||||
}
|
||||
|
||||
err = self.getFsStats(stats)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return stats, err
|
||||
}
|
||||
|
||||
// Fill in network stats for root.
|
||||
|
3
fs/fs.go
3
fs/fs.go
@ -67,6 +67,7 @@ func NewFsInfo() (FsInfo, error) {
|
||||
}
|
||||
partitions[mount.Source] = partition{mount.Mountpoint, uint(mount.Major), uint(mount.Minor)}
|
||||
}
|
||||
glog.Infof("Filesystem partitions: %+v", partitions)
|
||||
return &RealFsInfo{partitions}, nil
|
||||
}
|
||||
|
||||
@ -80,7 +81,7 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er
|
||||
for device, partition := range self.partitions {
|
||||
_, hasMount := mountSet[partition.mountpoint]
|
||||
_, hasDevice := deviceSet[device]
|
||||
if mountSet == nil || hasMount && !hasDevice {
|
||||
if mountSet == nil || (hasMount && !hasDevice) {
|
||||
total, free, err := getVfsStats(partition.mountpoint)
|
||||
if err != nil {
|
||||
glog.Errorf("Statvfs failed. Error: %v", err)
|
||||
|
@ -244,18 +244,20 @@ func (c *containerData) updateLoad(newLoad uint64) {
|
||||
}
|
||||
|
||||
func (c *containerData) updateStats() error {
|
||||
stats, err := c.handler.GetStats()
|
||||
if err != nil {
|
||||
stats, statsErr := c.handler.GetStats()
|
||||
if statsErr != nil {
|
||||
// Ignore errors if the container is dead.
|
||||
if !c.handler.Exists() {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
|
||||
// Stats may be partially populated, push those before we return an error.
|
||||
}
|
||||
if stats == nil {
|
||||
return nil
|
||||
return statsErr
|
||||
}
|
||||
if c.loadReader != nil {
|
||||
// TODO(vmarmol): Cache this path.
|
||||
path, err := c.handler.GetCgroupPath("cpu")
|
||||
if err == nil {
|
||||
loadStats, err := c.loadReader.GetCpuLoad(c.info.Name, path)
|
||||
@ -280,7 +282,7 @@ func (c *containerData) updateStats() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return statsErr
|
||||
}
|
||||
|
||||
func (c *containerData) updateSubcontainers() error {
|
||||
|
Loading…
Reference in New Issue
Block a user