diff --git a/plugins/inputs/system/cpu.go b/plugins/inputs/system/cpu.go index f60cb20c9..55378c93e 100644 --- a/plugins/inputs/system/cpu.go +++ b/plugins/inputs/system/cpu.go @@ -11,7 +11,7 @@ import ( type CPUStats struct { ps PS - lastStats []cpu.TimesStat + lastStats map[string]cpu.TimesStat PerCPU bool `toml:"percpu"` TotalCPU bool `toml:"totalcpu"` @@ -53,7 +53,7 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error { } now := time.Now() - for i, cts := range times { + for _, cts := range times { tags := map[string]string{ "cpu": cts.CPU, } @@ -86,13 +86,16 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error { // If it's the 1st gather, can't get CPU Usage stats yet continue } - lastCts := s.lastStats[i] + + lastCts, ok := s.lastStats[cts.CPU] + if !ok { + continue + } lastTotal := totalCpuTime(lastCts) lastActive := activeCpuTime(lastCts) totalDelta := total - lastTotal if totalDelta < 0 { - s.lastStats = times return fmt.Errorf("Error: current total CPU time is less than previous total CPU time") } @@ -118,7 +121,10 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error { acc.AddGauge("cpu", fieldsG, tags, now) } - s.lastStats = times + s.lastStats = make(map[string]cpu.TimesStat) + for _, cts := range times { + s.lastStats[cts.CPU] = cts + } return nil } diff --git a/plugins/inputs/system/cpu_test.go b/plugins/inputs/system/cpu_test.go index e9dc7dda9..fabff8a7d 100644 --- a/plugins/inputs/system/cpu_test.go +++ b/plugins/inputs/system/cpu_test.go @@ -149,3 +149,38 @@ func assertContainsTaggedFloat( measurement, delta, expectedValue, actualValue) assert.Fail(t, msg) } + +// TestCPUCountChange tests that no errors are encountered if the number of +// CPUs increases as reported with LXC. +func TestCPUCountIncrease(t *testing.T) { + var mps MockPS + var mps2 MockPS + var acc testutil.Accumulator + var err error + + cs := NewCPUStats(&mps) + + mps.On("CPUTimes").Return( + []cpu.TimesStat{ + cpu.TimesStat{ + CPU: "cpu0", + }, + }, nil) + + err = cs.Gather(&acc) + require.NoError(t, err) + + mps2.On("CPUTimes").Return( + []cpu.TimesStat{ + cpu.TimesStat{ + CPU: "cpu0", + }, + cpu.TimesStat{ + CPU: "cpu1", + }, + }, nil) + cs.ps = &mps2 + + err = cs.Gather(&acc) + require.NoError(t, err) +}