From 9a76da999389b38acce13d11fa0db347a2cd2c29 Mon Sep 17 00:00:00 2001 From: Rohit Jnagal Date: Mon, 22 Sep 2014 22:48:59 +0000 Subject: [PATCH] Add diskio stats to cAdvisor. Docker-DCO-1.1-Signed-off-by: Rohit Jnagal (github: rjnagal) --- container/libcontainer/helpers.go | 42 +++++++++++++++++++++++++++++++ info/container.go | 14 +++++++++++ 2 files changed, 56 insertions(+) diff --git a/container/libcontainer/helpers.go b/container/libcontainer/helpers.go index 0b14565d..c48bdbb9 100644 --- a/container/libcontainer/helpers.go +++ b/container/libcontainer/helpers.go @@ -15,6 +15,7 @@ package libcontainer import ( + "fmt" "time" "github.com/docker/libcontainer" @@ -41,6 +42,40 @@ func GetStatsCgroupOnly(cgroup *cgroups.Cgroup) (*info.ContainerStats, error) { return toContainerStats(&libcontainer.ContainerStats{CgroupStats: s}), nil } +func DiskStatsCopy(blkio_stats []cgroups.BlkioStatEntry) (stat []info.PerDiskStats) { + if len(blkio_stats) == 0 { + return + } + disk_stat := make(map[string]*info.PerDiskStats) + for i := range blkio_stats { + major := blkio_stats[i].Major + minor := blkio_stats[i].Minor + device_string := fmt.Sprintf("%d:%d", major, minor) + diskp, ok := disk_stat[device_string] + if !ok { + disk := info.PerDiskStats{ + Major: major, + Minor: minor, + } + disk.Stats = make(map[string]uint64) + diskp = &disk + disk_stat[device_string] = diskp + } + op := blkio_stats[i].Op + if op == "" { + op = "Count" + } + diskp.Stats[op] = blkio_stats[i].Value + } + i := 0 + stat = make([]info.PerDiskStats, len(disk_stat)) + for _, disk := range disk_stat { + stat[i] = *disk + i++ + } + return +} + // Convert libcontainer stats to info.ContainerStats. func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.ContainerStats { s := libcontainerStats.CgroupStats @@ -59,6 +94,13 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont ret.Cpu.Usage.PerCpu[i] = s.CpuStats.CpuUsage.PercpuUsage[i] ret.Cpu.Usage.Total += s.CpuStats.CpuUsage.PercpuUsage[i] } + + ret.DiskIo = new(info.DiskIoStats) + ret.DiskIo.IoServiceBytes = DiskStatsCopy(s.BlkioStats.IoServiceBytesRecursive) + ret.DiskIo.IoServiced = DiskStatsCopy(s.BlkioStats.IoServicedRecursive) + ret.DiskIo.IoQueued = DiskStatsCopy(s.BlkioStats.IoQueuedRecursive) + ret.DiskIo.Sectors = DiskStatsCopy(s.BlkioStats.SectorsRecursive) + ret.Memory = new(info.MemoryStats) ret.Memory.Usage = s.MemoryStats.Usage if v, ok := s.MemoryStats.Stats["pgfault"]; ok { diff --git a/info/container.go b/info/container.go index 7858fa53..8ab7af0c 100644 --- a/info/container.go +++ b/info/container.go @@ -166,6 +166,19 @@ type CpuStats struct { Load int32 `json:"load"` } +type PerDiskStats struct { + Major uint64 `json:"major"` + Minor uint64 `json:"minor"` + Stats map[string]uint64 `json:"stats"` +} + +type DiskIoStats struct { + IoServiceBytes []PerDiskStats `json:"io_service_bytes,omitempty"` + IoServiced []PerDiskStats `json:"io_serviced,omitempty"` + IoQueued []PerDiskStats `json:"io_queued,omitempty"` + Sectors []PerDiskStats `json"sectors,omitempty"` +} + type MemoryStats struct { // Memory limit, equivalent to "limit" in MemorySpec. // Units: Bytes. @@ -215,6 +228,7 @@ type ContainerStats struct { // The time of this stat point. Timestamp time.Time `json:"timestamp"` Cpu *CpuStats `json:"cpu,omitempty"` + DiskIo *DiskIoStats `json:"diskio,omitempty"` Memory *MemoryStats `json:"memory,omitempty"` Network *NetworkStats `json:"network,omitempty"` }