Adding filesystem usage information to MachineInfo.
This commit is contained in:
parent
6906a8ce90
commit
946b18f789
@ -24,10 +24,11 @@ import (
|
||||
|
||||
"code.google.com/p/go.exp/inotify"
|
||||
"github.com/docker/libcontainer/cgroups"
|
||||
"github.com/docker/libcontainer/cgroups/fs"
|
||||
cgroup_fs "github.com/docker/libcontainer/cgroups/fs"
|
||||
"github.com/golang/glog"
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/libcontainer"
|
||||
"github.com/google/cadvisor/fs"
|
||||
"github.com/google/cadvisor/info"
|
||||
"github.com/google/cadvisor/utils"
|
||||
)
|
||||
@ -40,6 +41,7 @@ type rawContainerHandler struct {
|
||||
watcher *inotify.Watcher
|
||||
stopWatcher chan error
|
||||
watches map[string]struct{}
|
||||
fsInfo fs.FsInfo
|
||||
}
|
||||
|
||||
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
|
||||
@ -53,6 +55,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, mac
|
||||
machineInfoFactory: machineInfoFactory,
|
||||
stopWatcher: make(chan error),
|
||||
watches: make(map[string]struct{}),
|
||||
fsInfo: fs.NewFsInfo(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -144,8 +147,18 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
func (self *rawContainerHandler) GetStats() (stats *info.ContainerStats, err error) {
|
||||
return libcontainer.GetStatsCgroupOnly(self.cgroup)
|
||||
func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
stats, err := libcontainer.GetStatsCgroupOnly(self.cgroup)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get Filesystem information
|
||||
fsStats, err := self.fsInfo.GetFsStats(self.name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stats.FsStats = fsStats
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// Lists all directories under "path" and outputs the results as children of "parent".
|
||||
@ -203,7 +216,7 @@ func (self *rawContainerHandler) ListThreads(listType container.ListType) ([]int
|
||||
}
|
||||
|
||||
func (self *rawContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {
|
||||
return fs.GetPids(self.cgroup)
|
||||
return cgroup_fs.GetPids(self.cgroup)
|
||||
}
|
||||
|
||||
func (self *rawContainerHandler) watchDirectory(dir string, containerName string) error {
|
||||
|
66
fs/fs.go
Normal file
66
fs/fs.go
Normal file
@ -0,0 +1,66 @@
|
||||
// +build linux
|
||||
//
|
||||
// Provides Filesystem Stats
|
||||
package fs
|
||||
|
||||
/*
|
||||
extern int getBytesFree(const char *path, unsigned long long *bytes);
|
||||
extern int getBytesTotal(const char *path, unsigned long long *bytes);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const EXT_SUPER_MAGIC = 0xEF53
|
||||
|
||||
type FsInfoImpl struct{}
|
||||
|
||||
func NewFsInfo() FsInfo {
|
||||
return &FsInfoImpl{}
|
||||
}
|
||||
|
||||
func (*FsInfoImpl) GetFsStats(containerName string) ([]FsStat, error) {
|
||||
filesystems := make([]FsStat, 0)
|
||||
if containerName != "/" {
|
||||
return filesystems, nil
|
||||
}
|
||||
mounts, err := mount.GetMounts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, mount := range mounts {
|
||||
if !strings.HasPrefix("ext", mount.FsType) || mount.Mountpoint != mount.Root {
|
||||
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})
|
||||
}
|
||||
}
|
||||
return filesystems, nil
|
||||
}
|
||||
|
||||
func getVfsStats(path string) (total uint64, free uint64, err error) {
|
||||
_p0, err := syscall.BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
res, err := C.getBytesFree((*C.char)(unsafe.Pointer(_p0)), (*_Ctype_ulonglong)(unsafe.Pointer(&free)))
|
||||
if res != 0 {
|
||||
return 0, 0, err
|
||||
}
|
||||
res, err = C.getBytesTotal((*C.char)(unsafe.Pointer(_p0)), (*_Ctype_ulonglong)(unsafe.Pointer(&total)))
|
||||
if res != 0 {
|
||||
return 0, 0, err
|
||||
}
|
||||
return total, free, nil
|
||||
}
|
23
fs/statvfs.c
Normal file
23
fs/statvfs.c
Normal file
@ -0,0 +1,23 @@
|
||||
// +build cgo
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
int getBytesFree(const char *path, unsigned long long *bytes) {
|
||||
struct statvfs buf;
|
||||
int res;
|
||||
if ((res = statvfs(path, &buf)) && res != 0) {
|
||||
return -1;
|
||||
}
|
||||
*bytes = buf.f_frsize * buf.f_bfree;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getBytesTotal(const char *path, unsigned long long *bytes) {
|
||||
struct statvfs buf;
|
||||
int res;
|
||||
if ((res = statvfs(path, &buf)) && res != 0) {
|
||||
return -1;
|
||||
}
|
||||
*bytes = buf.f_frsize * buf.f_blocks;
|
||||
return 0;
|
||||
}
|
12
fs/types.go
Normal file
12
fs/types.go
Normal file
@ -0,0 +1,12 @@
|
||||
package fs
|
||||
|
||||
type FsStat struct {
|
||||
Name string `json:"name"`
|
||||
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)
|
||||
}
|
@ -17,6 +17,8 @@ package info
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/fs"
|
||||
)
|
||||
|
||||
type CpuSpec struct {
|
||||
@ -236,6 +238,8 @@ type ContainerStats struct {
|
||||
DiskIo DiskIoStats `json:"diskio,omitempty"`
|
||||
Memory *MemoryStats `json:"memory,omitempty"`
|
||||
Network *NetworkStats `json:"network,omitempty"`
|
||||
// Filesystem statistics
|
||||
FsStats []fs.FsStat `json:"fs_stats,omitempty"`
|
||||
}
|
||||
|
||||
// Makes a deep copy of the ContainerStats and returns a pointer to the new
|
||||
|
Loading…
Reference in New Issue
Block a user