Add optional usage_active and time_active CPU metrics (#2943)

This commit is contained in:
Bob Shannon 2017-06-26 18:13:38 -04:00 committed by Daniel Nelson
parent 6f803308c5
commit d7af1b797c
3 changed files with 25 additions and 0 deletions

View File

@ -14,6 +14,8 @@
totalcpu = true totalcpu = true
## If true, collect raw CPU time metrics. ## If true, collect raw CPU time metrics.
collect_cpu_time = false collect_cpu_time = false
## If true, compute and report the sum of all non-idle CPU states.
report_active = false
``` ```
#### Description #### Description
@ -68,6 +70,7 @@ Measurement names:
- cpu_time_user - cpu_time_user
- cpu_time_system - cpu_time_system
- cpu_time_idle - cpu_time_idle
- cpu_time_active (must be explicitly enabled by setting `report_active = true`)
- cpu_time_nice - cpu_time_nice
- cpu_time_iowait - cpu_time_iowait
- cpu_time_irq - cpu_time_irq
@ -86,6 +89,7 @@ Measurement names:
- cpu_usage_user - cpu_usage_user
- cpu_usage_system - cpu_usage_system
- cpu_usage_idle - cpu_usage_idle
- cpu_usage_active (must be explicitly enabled by setting `report_active = true`)
- cpu_usage_nice - cpu_usage_nice
- cpu_usage_iowait - cpu_usage_iowait
- cpu_usage_irq - cpu_usage_irq

View File

@ -16,12 +16,14 @@ type CPUStats struct {
PerCPU bool `toml:"percpu"` PerCPU bool `toml:"percpu"`
TotalCPU bool `toml:"totalcpu"` TotalCPU bool `toml:"totalcpu"`
CollectCPUTime bool `toml:"collect_cpu_time"` CollectCPUTime bool `toml:"collect_cpu_time"`
ReportActive bool `toml:"report_active"`
} }
func NewCPUStats(ps PS) *CPUStats { func NewCPUStats(ps PS) *CPUStats {
return &CPUStats{ return &CPUStats{
ps: ps, ps: ps,
CollectCPUTime: true, CollectCPUTime: true,
ReportActive: true,
} }
} }
@ -36,6 +38,8 @@ var sampleConfig = `
totalcpu = true totalcpu = true
## If true, collect raw CPU time metrics. ## If true, collect raw CPU time metrics.
collect_cpu_time = false collect_cpu_time = false
## If true, compute and report the sum of all non-idle CPU states.
report_active = false
` `
func (_ *CPUStats) SampleConfig() string { func (_ *CPUStats) SampleConfig() string {
@ -55,6 +59,7 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error {
} }
total := totalCpuTime(cts) total := totalCpuTime(cts)
active := activeCpuTime(cts)
if s.CollectCPUTime { if s.CollectCPUTime {
// Add cpu time metrics // Add cpu time metrics
@ -70,6 +75,9 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error {
"time_guest": cts.Guest, "time_guest": cts.Guest,
"time_guest_nice": cts.GuestNice, "time_guest_nice": cts.GuestNice,
} }
if s.ReportActive {
fieldsC["time_active"] = activeCpuTime(cts)
}
acc.AddCounter("cpu", fieldsC, tags, now) acc.AddCounter("cpu", fieldsC, tags, now)
} }
@ -80,6 +88,7 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error {
} }
lastCts := s.lastStats[i] lastCts := s.lastStats[i]
lastTotal := totalCpuTime(lastCts) lastTotal := totalCpuTime(lastCts)
lastActive := activeCpuTime(lastCts)
totalDelta := total - lastTotal totalDelta := total - lastTotal
if totalDelta < 0 { if totalDelta < 0 {
@ -90,6 +99,7 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error {
if totalDelta == 0 { if totalDelta == 0 {
continue continue
} }
fieldsG := map[string]interface{}{ fieldsG := map[string]interface{}{
"usage_user": 100 * (cts.User - lastCts.User - (cts.Guest - lastCts.Guest)) / totalDelta, "usage_user": 100 * (cts.User - lastCts.User - (cts.Guest - lastCts.Guest)) / totalDelta,
"usage_system": 100 * (cts.System - lastCts.System) / totalDelta, "usage_system": 100 * (cts.System - lastCts.System) / totalDelta,
@ -102,6 +112,9 @@ func (s *CPUStats) Gather(acc telegraf.Accumulator) error {
"usage_guest": 100 * (cts.Guest - lastCts.Guest) / totalDelta, "usage_guest": 100 * (cts.Guest - lastCts.Guest) / totalDelta,
"usage_guest_nice": 100 * (cts.GuestNice - lastCts.GuestNice) / totalDelta, "usage_guest_nice": 100 * (cts.GuestNice - lastCts.GuestNice) / totalDelta,
} }
if s.ReportActive {
fieldsG["usage_active"] = 100 * (active - lastActive) / totalDelta
}
acc.AddGauge("cpu", fieldsG, tags, now) acc.AddGauge("cpu", fieldsG, tags, now)
} }
@ -116,6 +129,11 @@ func totalCpuTime(t cpu.TimesStat) float64 {
return total return total
} }
func activeCpuTime(t cpu.TimesStat) float64 {
active := totalCpuTime(t) - t.Idle
return active
}
func init() { func init() {
inputs.Add("cpu", func() telegraf.Input { inputs.Add("cpu", func() telegraf.Input {
return &CPUStats{ return &CPUStats{

View File

@ -59,6 +59,7 @@ func TestCPUStats(t *testing.T) {
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 8.8, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 8.8, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 8.2, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 8.2, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 80.1, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 80.1, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_active", 19.9, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 1.3, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 1.3, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.8389, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.8389, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 0.6, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 0.6, 0, cputags)
@ -78,6 +79,7 @@ func TestCPUStats(t *testing.T) {
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 24.9, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 24.9, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 10.9, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 10.9, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 157.9798, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 157.9798, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_active", 42.0202, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 3.5, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 3.5, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.929, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.929, 0, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 1.2, 0, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 1.2, 0, cputags)
@ -89,6 +91,7 @@ func TestCPUStats(t *testing.T) {
assertContainsTaggedFloat(t, &acc, "cpu", "usage_user", 7.8, 0.0005, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "usage_user", 7.8, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "usage_system", 2.7, 0.0005, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "usage_system", 2.7, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "usage_idle", 77.8798, 0.0005, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "usage_idle", 77.8798, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "usage_active", 22.1202, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "usage_nice", 0, 0.0005, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "usage_nice", 0, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "usage_iowait", 0.0901, 0.0005, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "usage_iowait", 0.0901, 0.0005, cputags)
assertContainsTaggedFloat(t, &acc, "cpu", "usage_irq", 0.6, 0.0005, cputags) assertContainsTaggedFloat(t, &acc, "cpu", "usage_irq", 0.6, 0.0005, cputags)