diff --git a/cadvisor b/cadvisor deleted file mode 100755 index 15b16f30..00000000 Binary files a/cadvisor and /dev/null differ diff --git a/info/container.go b/info/container.go index 94c7c657..3e2447d9 100644 --- a/info/container.go +++ b/info/container.go @@ -119,7 +119,7 @@ type CpuStats struct { // Per CPU/core usage of the container. // Unit: nanoseconds. - PerCpu []uint64 `json:"per_cpu,omitempty"` + PerCpu []uint64 `json:"per_cpu_usage,omitempty"` // Time spent in user space. // Unit: nanoseconds @@ -173,6 +173,9 @@ type ContainerStatsSample struct { Cpu struct { // number of nanoseconds of CPU time used by the container Usage uint64 `json:"usage"` + + // Per-core usage of the container. (unit: nanoseconds) + PerCpuUsage []uint64 `json:"per_cpu_usage,omitempty"` } `json:"cpu"` Memory struct { // Units: Bytes. @@ -211,9 +214,28 @@ func NewSample(prev, current *ContainerStats) (*ContainerStatsSample, error) { if current.Cpu.Usage.Total < prev.Cpu.Usage.Total { return nil, fmt.Errorf("current CPU usage is less than prev CPU usage (cumulative).") } + + var percpu []uint64 + + if len(current.Cpu.Usage.PerCpu) > 0 { + curNumCpus := len(current.Cpu.Usage.PerCpu) + percpu = make([]uint64, curNumCpus) + + for i, currUsage := range current.Cpu.Usage.PerCpu { + var prevUsage uint64 = 0 + if i < len(prev.Cpu.Usage.PerCpu) { + prevUsage = prev.Cpu.Usage.PerCpu[i] + } + if currUsage < prevUsage { + return nil, fmt.Errorf("current per-core CPU usage is less than prev per-core CPU usage (cumulative).") + } + percpu[i] = currUsage - prevUsage + } + } sample := new(ContainerStatsSample) // Calculate the diff to get the CPU usage within the time interval. sample.Cpu.Usage = current.Cpu.Usage.Total - prev.Cpu.Usage.Total + sample.Cpu.PerCpuUsage = percpu // Memory usage is current memory usage sample.Memory.Usage = current.Memory.Usage sample.Timestamp = current.Timestamp diff --git a/info/container_test.go b/info/container_test.go index 4b275bec..071ed914 100644 --- a/info/container_test.go +++ b/info/container_test.go @@ -230,3 +230,50 @@ func TestAddSampleWrongCpuUsage(t *testing.T) { t.Errorf("generated an unexpected sample: %+v", sample) } } + +func TestAddSampleHotPluggingCpu(t *testing.T) { + cpuPrevUsage := uint64(10) + cpuCurrentUsage := uint64(15) + memCurrentUsage := uint64(200) + prevTime := time.Now() + + prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime) + current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second)) + current.Cpu.Usage.PerCpu = append(current.Cpu.Usage.PerCpu, 10) + + sample, err := NewSample(prev, current) + if err != nil { + t.Errorf("should be able to generate a sample. but received error: %v", err) + } + if len(sample.Cpu.PerCpuUsage) != 2 { + t.Fatalf("Should have 2 cores.") + } + if sample.Cpu.PerCpuUsage[0] != cpuCurrentUsage-cpuPrevUsage { + t.Errorf("First cpu usage is %v. should be %v", sample.Cpu.PerCpuUsage[0], cpuCurrentUsage-cpuPrevUsage) + } + if sample.Cpu.PerCpuUsage[1] != 10 { + t.Errorf("Second cpu usage is %v. should be 10", sample.Cpu.PerCpuUsage[1]) + } +} + +func TestAddSampleHotUnpluggingCpu(t *testing.T) { + cpuPrevUsage := uint64(10) + cpuCurrentUsage := uint64(15) + memCurrentUsage := uint64(200) + prevTime := time.Now() + + prev := createStats(cpuPrevUsage, memCurrentUsage, prevTime) + current := createStats(cpuCurrentUsage, memCurrentUsage, prevTime.Add(1*time.Second)) + prev.Cpu.Usage.PerCpu = append(prev.Cpu.Usage.PerCpu, 10) + + sample, err := NewSample(prev, current) + if err != nil { + t.Errorf("should be able to generate a sample. but received error: %v", err) + } + if len(sample.Cpu.PerCpuUsage) != 1 { + t.Fatalf("Should have 1 cores.") + } + if sample.Cpu.PerCpuUsage[0] != cpuCurrentUsage-cpuPrevUsage { + t.Errorf("First cpu usage is %v. should be %v", sample.Cpu.PerCpuUsage[0], cpuCurrentUsage-cpuPrevUsage) + } +} diff --git a/storage/test/storagetests.go b/storage/test/storagetests.go index 7a45cc8a..9c4ec0ae 100644 --- a/storage/test/storagetests.go +++ b/storage/test/storagetests.go @@ -44,7 +44,7 @@ func buildTrace(cpu, mem []uint64, duration time.Duration) []*info.ContainerStat stats.Cpu.Usage.Total = cpuTotalUsage stats.Cpu.Usage.User = stats.Cpu.Usage.Total stats.Cpu.Usage.System = 0 - stats.Cpu.Usage.PerCpu = []uint64{cpuUsage} + stats.Cpu.Usage.PerCpu = []uint64{cpuTotalUsage} stats.Memory.Usage = mem[i]