From 9a76da999389b38acce13d11fa0db347a2cd2c29 Mon Sep 17 00:00:00 2001 From: Rohit Jnagal Date: Mon, 22 Sep 2014 22:48:59 +0000 Subject: [PATCH 1/2] 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"` } From 6aee4c03b0d38452b04ab0d9bf4ebd6c80f21d4b Mon Sep 17 00:00:00 2001 From: Rohit Jnagal Date: Mon, 22 Sep 2014 23:24:34 +0000 Subject: [PATCH 2/2] Flatten diskio stats and use struct key. Docker-DCO-1.1-Signed-off-by: Rohit Jnagal (github: rjnagal) --- container/libcontainer/helpers.go | 17 +++++++++++------ info/container.go | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/container/libcontainer/helpers.go b/container/libcontainer/helpers.go index c48bdbb9..6fd47a44 100644 --- a/container/libcontainer/helpers.go +++ b/container/libcontainer/helpers.go @@ -15,7 +15,6 @@ package libcontainer import ( - "fmt" "time" "github.com/docker/libcontainer" @@ -46,12 +45,19 @@ func DiskStatsCopy(blkio_stats []cgroups.BlkioStatEntry) (stat []info.PerDiskSta if len(blkio_stats) == 0 { return } - disk_stat := make(map[string]*info.PerDiskStats) + type DiskKey struct { + Major uint64 + Minor uint64 + } + disk_stat := make(map[DiskKey]*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] + disk_key := DiskKey{ + Major: major, + Minor: minor, + } + diskp, ok := disk_stat[disk_key] if !ok { disk := info.PerDiskStats{ Major: major, @@ -59,7 +65,7 @@ func DiskStatsCopy(blkio_stats []cgroups.BlkioStatEntry) (stat []info.PerDiskSta } disk.Stats = make(map[string]uint64) diskp = &disk - disk_stat[device_string] = diskp + disk_stat[disk_key] = diskp } op := blkio_stats[i].Op if op == "" { @@ -95,7 +101,6 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont 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) diff --git a/info/container.go b/info/container.go index 8ab7af0c..18ea9a2e 100644 --- a/info/container.go +++ b/info/container.go @@ -228,7 +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"` + DiskIo DiskIoStats `json:"diskio,omitempty"` Memory *MemoryStats `json:"memory,omitempty"` Network *NetworkStats `json:"network,omitempty"` }