diff --git a/metrics/linux/cpuusage.go b/metrics/linux/cpuusage.go index b860ec17d..582e8d7af 100644 --- a/metrics/linux/cpuusage.go +++ b/metrics/linux/cpuusage.go @@ -9,6 +9,7 @@ import ( "github.com/mackerelio/go-osstat/cpu" "github.com/mackerelio/golib/logging" "github.com/mackerelio/mackerel-agent/metrics" + "github.com/mackerelio/mackerel-agent/util" ) /* @@ -55,7 +56,7 @@ func (g *CPUUsageGenerator) Generate() (metrics.Values, error) { "cpu.idle.percentage": float64(current.Idle-previous.Idle) * cpuCount * 100.0 / totalDiff, } if current.StatCount >= 5 { - ret["cpu.iowait.percentage"] = float64(current.Iowait-previous.Iowait) * cpuCount * 100.0 / totalDiff + ret["cpu.iowait.percentage"] = float64(util.DiffResettableCounter(current.Iowait, previous.Iowait)) * cpuCount * 100.0 / totalDiff } if current.StatCount >= 6 { ret["cpu.irq.percentage"] = float64(current.Irq-previous.Irq) * cpuCount * 100.0 / totalDiff diff --git a/util/calc.go b/util/calc.go new file mode 100644 index 000000000..48df477d2 --- /dev/null +++ b/util/calc.go @@ -0,0 +1,11 @@ +package util + +// Calculate incremental difference of uint64 counters that can be reset. +// Avoiding overflow, return current value if it is smaller than previous one. +func DiffResettableCounter(current, previous uint64) uint64 { + if current < previous { + // counter has been reset + return current + } + return current - previous +} diff --git a/util/calc_test.go b/util/calc_test.go new file mode 100644 index 000000000..f0fa836f3 --- /dev/null +++ b/util/calc_test.go @@ -0,0 +1,25 @@ +package util + +import ( + "fmt" + "testing" +) + +func TestDiffResettableCounter(t *testing.T) { + cases := []struct { + inCurrent uint64 + inPrevious uint64 + want uint64 + }{ + {100, 30, 70}, + {20, 50, 20}, // counter has been reset + } + for _, tt := range cases { + t.Run(fmt.Sprintf("%d - %d", tt.inCurrent, tt.inPrevious), func(t *testing.T) { + got := DiffResettableCounter(tt.inCurrent, tt.inPrevious) + if got != tt.want { + t.Errorf("want=%d, got=%d", tt.want, got) + } + }) + } +}