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:
parent
946b18f789
commit
b9e70f0240
@ -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 \
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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"]
|
||||
|
27
fs/fs.go
27
fs/fs.go
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user