package system import ( "fmt" "github.com/influxdb/telegraf/plugins" "github.com/influxdb/telegraf/plugins/system/ps/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` 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, } busy, total := busyAndTotalCpuTime(cts) // Add total cpu numbers add(acc, "user", cts.User, tags) add(acc, "system", cts.System, tags) add(acc, "idle", cts.Idle, tags) add(acc, "nice", cts.Nice, tags) add(acc, "iowait", cts.Iowait, tags) add(acc, "irq", cts.Irq, tags) add(acc, "softirq", cts.Softirq, tags) add(acc, "steal", cts.Steal, tags) add(acc, "guest", cts.Guest, tags) add(acc, "guestNice", cts.GuestNice, tags) add(acc, "stolen", cts.Stolen, tags) add(acc, "busy", busy, 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] lastBusy, lastTotal := busyAndTotalCpuTime(lastCts) busyDelta := busy - lastBusy 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, "percentageUser", 100*(cts.User-lastCts.User)/totalDelta, tags) add(acc, "percentageSystem", 100*(cts.System-lastCts.System)/totalDelta, tags) add(acc, "percentageIdle", 100*(cts.Idle-lastCts.Idle)/totalDelta, tags) add(acc, "percentageNice", 100*(cts.Nice-lastCts.Nice)/totalDelta, tags) add(acc, "percentageIowait", 100*(cts.Iowait-lastCts.Iowait)/totalDelta, tags) add(acc, "percentageIrq", 100*(cts.Irq-lastCts.Irq)/totalDelta, tags) add(acc, "percentageSoftirq", 100*(cts.Softirq-lastCts.Softirq)/totalDelta, tags) add(acc, "percentageSteal", 100*(cts.Steal-lastCts.Steal)/totalDelta, tags) add(acc, "percentageGuest", 100*(cts.Guest-lastCts.Guest)/totalDelta, tags) add(acc, "percentageGuestNice", 100*(cts.GuestNice-lastCts.GuestNice)/totalDelta, tags) add(acc, "percentageStolen", 100*(cts.Stolen-lastCts.Stolen)/totalDelta, tags) add(acc, "percentageBusy", 100*busyDelta/totalDelta, tags) } s.lastStats = times return nil } func busyAndTotalCpuTime(t cpu.CPUTimesStat) (float64, float64) { busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen return busy, busy + t.Idle } func init() { plugins.Add("cpu", func() plugins.Plugin { return &CPUStats{ps: &systemPS{}} }) }