Fix panic in cpu input if number of cpus changes (#3306)

(cherry picked from commit f56dda0ac8)
This commit is contained in:
Daniel Nelson 2017-10-05 16:02:21 -07:00 committed by Daniel Nelson
parent b8ab827629
commit f7b3eb1ebd
No known key found for this signature in database
GPG Key ID: CAAD59C9444F6155
2 changed files with 46 additions and 5 deletions

View File

@ -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
}

View File

@ -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)
}