package system import ( "fmt" "github.com/influxdb/telegraf/plugins" "github.com/shirou/gopsutil/cpu" ) type CPUStats struct { ps PS lastStats []cpu.CPUTimesStat PerCPU bool `toml:"percpu"` TotalCPU bool `toml:"totalcpu"` } func NewCPUStats(ps PS) *CPUStats { return &CPUStats{ ps: ps, } } func (_ *CPUStats) Description() string { return "Read metrics about cpu usage" } var sampleConfig = ` # Whether to report per-cpu stats or not percpu = true # Whether to report total system cpu stats or not totalcpu = true # Comment this line if you want the raw CPU time metrics drop = ["cpu_time"] ` func (_ *CPUStats) SampleConfig() string { return sampleConfig } func (s *CPUStats) Gather(acc plugins.Accumulator) error { times, err := s.ps.CPUTimes(s.PerCPU, s.TotalCPU) if err != nil { return fmt.Errorf("error getting CPU info: %s", err) } for i, cts := range times { tags := map[string]string{ "cpu": cts.CPU, } total := totalCpuTime(cts) // Add total cpu numbers add(acc, "time_user", cts.User, tags) add(acc, "time_system", cts.System, tags) add(acc, "time_idle", cts.Idle, tags) add(acc, "time_nice", cts.Nice, tags) add(acc, "time_iowait", cts.Iowait, tags) add(acc, "time_irq", cts.Irq, tags) add(acc, "time_softirq", cts.Softirq, tags) add(acc, "time_steal", cts.Steal, tags) add(acc, "time_guest", cts.Guest, tags) add(acc, "time_guest_nice", cts.GuestNice, tags) // Add in percentage if len(s.lastStats) == 0 { // If it's the 1st gather, can't get CPU stats yet continue } lastCts := s.lastStats[i] lastTotal := totalCpuTime(lastCts) totalDelta := total - lastTotal if totalDelta < 0 { return fmt.Errorf("Error: current total CPU time is less than previous total CPU time") } if totalDelta == 0 { continue } add(acc, "usage_user", 100*(cts.User-lastCts.User)/totalDelta, tags) add(acc, "usage_system", 100*(cts.System-lastCts.System)/totalDelta, tags) add(acc, "usage_idle", 100*(cts.Idle-lastCts.Idle)/totalDelta, tags) add(acc, "usage_nice", 100*(cts.Nice-lastCts.Nice)/totalDelta, tags) add(acc, "usage_iowait", 100*(cts.Iowait-lastCts.Iowait)/totalDelta, tags) add(acc, "usage_irq", 100*(cts.Irq-lastCts.Irq)/totalDelta, tags) add(acc, "usage_softirq", 100*(cts.Softirq-lastCts.Softirq)/totalDelta, tags) add(acc, "usage_steal", 100*(cts.Steal-lastCts.Steal)/totalDelta, tags) add(acc, "usage_guest", 100*(cts.Guest-lastCts.Guest)/totalDelta, tags) add(acc, "usage_guest_nice", 100*(cts.GuestNice-lastCts.GuestNice)/totalDelta, tags) } s.lastStats = times return nil } func totalCpuTime(t cpu.CPUTimesStat) float64 { total := t.User + t.System + t.Nice + t.Iowait + t.Irq + t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Idle return total } func init() { plugins.Add("cpu", func() plugins.Plugin { return &CPUStats{ps: &systemPS{}} }) }