Filesystem stats are now per container. As of now, fs stats are reported only for the

root cgroup.
To make cadvisor detect all the disks, the rootfs of host needs to mounted
inside cadvisor.
This commit is contained in:
Vishnu Kannan 2014-09-29 23:21:13 +00:00
parent 946b18f789
commit b9e70f0240
6 changed files with 42 additions and 21 deletions

View File

@ -12,6 +12,7 @@ To quickly tryout cAdvisor on your machine with Docker (version 0.11 or above),
```
sudo docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \

View File

@ -41,7 +41,7 @@ type rawContainerHandler struct {
watcher *inotify.Watcher
stopWatcher chan error
watches map[string]struct{}
fsInfo fs.FsInfo
fsInfo fs.FsInfo
}
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
@ -55,7 +55,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, mac
machineInfoFactory: machineInfoFactory,
stopWatcher: make(chan error),
watches: make(map[string]struct{}),
fsInfo: fs.NewFsInfo(),
fsInfo: fs.NewFsInfo(),
}, nil
}
@ -144,6 +144,10 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
}
}
// Fs.
if self.name == "/" {
spec.HasFs = true
}
return spec, nil
}
@ -152,12 +156,14 @@ func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
if err != nil {
return nil, err
}
// Get Filesystem information
fsStats, err := self.fsInfo.GetFsStats(self.name)
if err != nil {
return nil, err
// Get Filesystem information only for the root cgroup.
if self.name == "/" {
stats.Fs, err = self.fsInfo.GetFsStats()
if err != nil {
return nil, err
}
}
stats.FsStats = fsStats
return stats, nil
}

View File

@ -3,6 +3,7 @@ MAINTAINER dengnan@google.com vmarmol@google.com vishnuk@google.com
# Grab cadvisor from the staging directory.
ADD cadvisor /usr/bin/cadvisor
RUN mkdir /rootfs
EXPOSE 8080
ENTRYPOINT ["/usr/bin/cadvisor"]

View File

@ -10,6 +10,7 @@ package fs
import "C"
import (
"strings"
"syscall"
"unsafe"
@ -17,33 +18,41 @@ import (
"github.com/golang/glog"
)
const EXT_SUPER_MAGIC = 0xEF53
type FsInfoImpl struct{}
func NewFsInfo() FsInfo {
return &FsInfoImpl{}
}
func (*FsInfoImpl) GetFsStats(containerName string) ([]FsStat, error) {
func (*FsInfoImpl) GetFsStats() ([]FsStat, error) {
filesystems := make([]FsStat, 0)
if containerName != "/" {
return filesystems, nil
}
mounts, err := mount.GetMounts()
if err != nil {
return nil, err
}
processedPartitions := make(map[string]bool, 0)
for _, mount := range mounts {
if !strings.HasPrefix("ext", mount.FsType) || mount.Mountpoint != mount.Root {
if !strings.HasPrefix(mount.Fstype, "ext") {
continue
}
// Avoid bind mounts.
if _, ok := processedPartitions[mount.Source]; ok {
continue
}
total, free, err := getVfsStats(mount.Mountpoint)
if err != nil {
glog.Errorf("Statvfs failed. Error: %v", err)
} else {
glog.V(1).Infof("%s is an ext partition at %s. Total: %d, Free: %d", mount.Source, mount.Mountpoint, total, free)
filesystems = append(filesystems, FsStat{mount.Source, total, free})
glog.V(1).Infof("%s is an %s partition at %s. Total: %d, Free: %d", mount.Source, mount.Fstype, mount.Mountpoint, total, free)
fsStat := FsStat{
Device: mount.Source,
Major: uint(mount.Major),
Minor: uint(mount.Minor),
Capacity: total,
Free: free,
}
filesystems = append(filesystems, fsStat)
processedPartitions[mount.Source] = true
}
}
return filesystems, nil

View File

@ -1,12 +1,14 @@
package fs
type FsStat struct {
Name string `json:"name"`
Device string `json:"device,omitempty"`
Major uint `json:"major"`
Minor uint `json:"minor"`
Capacity uint64 `json:"capacity"`
Free uint64 `json:"free"`
}
type FsInfo interface {
// Returns capacity and free space, in bytes, of all the ext2, ext3, ext4 filesystems used by container 'containerName'.
GetFsStats(containerName string) ([]FsStat, error)
// Returns capacity and free space, in bytes, of all the ext2, ext3, ext4 filesystems on the host.
GetFsStats() ([]FsStat, error)
}

View File

@ -17,7 +17,7 @@ package info
import (
"reflect"
"time"
"github.com/google/cadvisor/fs"
)
@ -49,6 +49,8 @@ type ContainerSpec struct {
Memory MemorySpec `json:"memory,omitempty"`
HasNetwork bool `json:"has_network"`
HasFs bool `json:"has_fs"`
}
// Container reference contains enough information to uniquely identify a container
@ -239,7 +241,7 @@ type ContainerStats struct {
Memory *MemoryStats `json:"memory,omitempty"`
Network *NetworkStats `json:"network,omitempty"`
// Filesystem statistics
FsStats []fs.FsStat `json:"fs_stats,omitempty"`
Fs []fs.FsStat `json:"fs,omitempty"`
}
// Makes a deep copy of the ContainerStats and returns a pointer to the new