From 5e91c1226f54ba26c95c10efe09a18b78964d42c Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 21:05:25 +0800 Subject: [PATCH 01/26] Download psi.go from https://github.com/gridscale/linux-psi-telegraf-plugin --- plugins/inputs/psi/psi.go | 197 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 plugins/inputs/psi/psi.go diff --git a/plugins/inputs/psi/psi.go b/plugins/inputs/psi/psi.go new file mode 100644 index 0000000000000..fc84abe9482c1 --- /dev/null +++ b/plugins/inputs/psi/psi.go @@ -0,0 +1,197 @@ +package psi + +import ( + "log" + + "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/plugins/inputs" + "github.com/prometheus/procfs" +) + +// Psi - Plugins main structure + +type Psi struct{} + +// Description returns the plugin description +func (psi *Psi) Description() string { + return ` + A plugin to gather resource pressure metrics from the Linux kernel. + Pressure Stall Information (PSI) is available at + "/proc/pressure/" -- cpu, memory and io. + + Examples: + /proc/pressure/cpu + some avg10=1.53 avg60=1.87 avg300=1.73 total=1088168194 + + /proc/pressure/memory + some avg10=0.00 avg60=0.00 avg300=0.00 total=3463792 + full avg10=0.00 avg60=0.00 avg300=0.00 total=1429641 + + /proc/pressure/io + some avg10=0.00 avg60=0.00 avg300=0.00 total=68568296 + full avg10=0.00 avg60=0.00 avg300=0.00 total=54982338 + ` +} + +// SampleConfig returns sample configuration for this plugin +func (psi *Psi) SampleConfig() string { + return ` + [[inputs.execd]] + command = ["/usr/local/bin/psi"] + signal = "none" + ` +} + +// Gather Psi metrics +func (psi *Psi) Gather(acc telegraf.Accumulator) error { + + cpuPressure, memoryPressure, ioPressure, err := psi.getPressureValues() + if err == nil { + psi.uploadPressure(cpuPressure, memoryPressure, ioPressure, acc) + } + + return nil +} + +// run initially when the package is imported +func init() { + inputs.Add("psi", func() telegraf.Input { return &Psi{} }) +} + +// getPressureValues - Get the pressure values from /proc/pressure/* +func (psi *Psi) getPressureValues() (cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, err error) { + procfs, err := procfs.NewFS("/proc") + if err != nil { + log.Fatalf("proc not available: %s", err) + } + + cpuPressure, err = procfs.PSIStatsForResource("cpu") + if err != nil { + log.Fatalf("No CPU pressure found: %s", err) + } + + memoryPressure, err = procfs.PSIStatsForResource("memory") + if err != nil { + log.Fatalf("No memory pressure found: %s", err) + } + + ioPressure, err = procfs.PSIStatsForResource("io") + if err != nil { + log.Fatalf("No io pressure found: %s", err) + } + + return cpuPressure, memoryPressure, ioPressure, nil + +} + +// uploadPressure Uploads all pressure value to corrosponding fields +func (psi *Psi) uploadPressure(cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, acc telegraf.Accumulator) { + + // pressureTotal some + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": cpuPressure.Some.Total, + }, + map[string]string{ + "resource": "cpu", + "type": "some", + }, + ) + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": memoryPressure.Some.Total, + }, + map[string]string{ + "resource": "memory", + "type": "some", + }, + ) + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": ioPressure.Some.Total, + }, + map[string]string{ + "resource": "io", + "type": "some", + }, + ) + + // pressureTotal full + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": memoryPressure.Full.Total, + }, + map[string]string{ + "resource": "memory", + "type": "full", + }, + ) + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": ioPressure.Full.Total, + }, + map[string]string{ + "resource": "io", + "type": "full", + }, + ) + + // pressure some + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": cpuPressure.Some.Avg10, + "avg60": cpuPressure.Some.Avg60, + "avg300": cpuPressure.Some.Avg300, + }, + map[string]string{ + "resource": "cpu", + "type": "some", + }, + ) + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": memoryPressure.Some.Avg10, + "avg60": memoryPressure.Some.Avg60, + "avg300": memoryPressure.Some.Avg300, + }, + map[string]string{ + "resource": "memory", + "type": "some", + }, + ) + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": ioPressure.Some.Avg10, + "avg60": ioPressure.Some.Avg60, + "avg300": ioPressure.Some.Avg300, + }, + map[string]string{ + "resource": "io", + "type": "some", + }, + ) + + // pressure full + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": memoryPressure.Full.Avg10, + "avg60": memoryPressure.Full.Avg60, + "avg300": memoryPressure.Full.Avg300, + }, + map[string]string{ + "resource": "memory", + "type": "full", + }, + ) + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": ioPressure.Full.Avg10, + "avg60": ioPressure.Full.Avg60, + "avg300": ioPressure.Full.Avg300, + }, + map[string]string{ + "resource": "io", + "type": "full", + }, + ) +} From 4b91d153f5876e80ad92c08f5df9db59c6127556 Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 21:22:20 +0800 Subject: [PATCH 02/26] psi: Split up psi.go, add sample.conf and README --- plugins/inputs/psi/README.md | 17 +++ plugins/inputs/psi/psi.go | 191 ++--------------------------- plugins/inputs/psi/psi_linux.go | 162 ++++++++++++++++++++++++ plugins/inputs/psi/psi_nonlinux.go | 10 ++ plugins/inputs/psi/sample.conf | 4 + 5 files changed, 206 insertions(+), 178 deletions(-) create mode 100644 plugins/inputs/psi/README.md create mode 100644 plugins/inputs/psi/psi_linux.go create mode 100644 plugins/inputs/psi/psi_nonlinux.go create mode 100644 plugins/inputs/psi/sample.conf diff --git a/plugins/inputs/psi/README.md b/plugins/inputs/psi/README.md new file mode 100644 index 0000000000000..aa82bc4cd00f2 --- /dev/null +++ b/plugins/inputs/psi/README.md @@ -0,0 +1,17 @@ +# Pressure Stall Information (PSI) Input Plugin + +A plugin to gather resource pressure metrics from the Linux kernel. +Pressure Stall Information (PSI) is available at +"/proc/pressure/" -- cpu, memory and io. + +Examples: +/proc/pressure/cpu +some avg10=1.53 avg60=1.87 avg300=1.73 total=1088168194 + +/proc/pressure/memory +some avg10=0.00 avg60=0.00 avg300=0.00 total=3463792 +full avg10=0.00 avg60=0.00 avg300=0.00 total=1429641 + +/proc/pressure/io +some avg10=0.00 avg60=0.00 avg300=0.00 total=68568296 +full avg10=0.00 avg60=0.00 avg300=0.00 total=54982338 diff --git a/plugins/inputs/psi/psi.go b/plugins/inputs/psi/psi.go index fc84abe9482c1..1d2901c0a30b6 100644 --- a/plugins/inputs/psi/psi.go +++ b/plugins/inputs/psi/psi.go @@ -1,197 +1,32 @@ package psi import ( - "log" + _ "embed" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/inputs" - "github.com/prometheus/procfs" ) // Psi - Plugins main structure - -type Psi struct{} - -// Description returns the plugin description -func (psi *Psi) Description() string { - return ` - A plugin to gather resource pressure metrics from the Linux kernel. - Pressure Stall Information (PSI) is available at - "/proc/pressure/" -- cpu, memory and io. - - Examples: - /proc/pressure/cpu - some avg10=1.53 avg60=1.87 avg300=1.73 total=1088168194 - - /proc/pressure/memory - some avg10=0.00 avg60=0.00 avg300=0.00 total=3463792 - full avg10=0.00 avg60=0.00 avg300=0.00 total=1429641 - - /proc/pressure/io - some avg10=0.00 avg60=0.00 avg300=0.00 total=68568296 - full avg10=0.00 avg60=0.00 avg300=0.00 total=54982338 - ` +type Psi struct { + Log telegraf.Logger `toml:"-"` } +//go:embed sample.conf +var sampleConfig string + // SampleConfig returns sample configuration for this plugin func (psi *Psi) SampleConfig() string { - return ` - [[inputs.execd]] - command = ["/usr/local/bin/psi"] - signal = "none" - ` + return sampleConfig } -// Gather Psi metrics -func (psi *Psi) Gather(acc telegraf.Accumulator) error { - - cpuPressure, memoryPressure, ioPressure, err := psi.getPressureValues() - if err == nil { - psi.uploadPressure(cpuPressure, memoryPressure, ioPressure, acc) - } - - return nil +// Description returns the plugin description +func (psi *Psi) Description() string { + return "Gather Pressure Stall Information (PSI) from /proc/pressure/" } -// run initially when the package is imported func init() { - inputs.Add("psi", func() telegraf.Input { return &Psi{} }) -} - -// getPressureValues - Get the pressure values from /proc/pressure/* -func (psi *Psi) getPressureValues() (cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, err error) { - procfs, err := procfs.NewFS("/proc") - if err != nil { - log.Fatalf("proc not available: %s", err) - } - - cpuPressure, err = procfs.PSIStatsForResource("cpu") - if err != nil { - log.Fatalf("No CPU pressure found: %s", err) - } - - memoryPressure, err = procfs.PSIStatsForResource("memory") - if err != nil { - log.Fatalf("No memory pressure found: %s", err) - } - - ioPressure, err = procfs.PSIStatsForResource("io") - if err != nil { - log.Fatalf("No io pressure found: %s", err) - } - - return cpuPressure, memoryPressure, ioPressure, nil - -} - -// uploadPressure Uploads all pressure value to corrosponding fields -func (psi *Psi) uploadPressure(cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, acc telegraf.Accumulator) { - - // pressureTotal some - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": cpuPressure.Some.Total, - }, - map[string]string{ - "resource": "cpu", - "type": "some", - }, - ) - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": memoryPressure.Some.Total, - }, - map[string]string{ - "resource": "memory", - "type": "some", - }, - ) - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": ioPressure.Some.Total, - }, - map[string]string{ - "resource": "io", - "type": "some", - }, - ) - - // pressureTotal full - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": memoryPressure.Full.Total, - }, - map[string]string{ - "resource": "memory", - "type": "full", - }, - ) - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": ioPressure.Full.Total, - }, - map[string]string{ - "resource": "io", - "type": "full", - }, - ) - - // pressure some - - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": cpuPressure.Some.Avg10, - "avg60": cpuPressure.Some.Avg60, - "avg300": cpuPressure.Some.Avg300, - }, - map[string]string{ - "resource": "cpu", - "type": "some", - }, - ) - - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": memoryPressure.Some.Avg10, - "avg60": memoryPressure.Some.Avg60, - "avg300": memoryPressure.Some.Avg300, - }, - map[string]string{ - "resource": "memory", - "type": "some", - }, - ) - - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": ioPressure.Some.Avg10, - "avg60": ioPressure.Some.Avg60, - "avg300": ioPressure.Some.Avg300, - }, - map[string]string{ - "resource": "io", - "type": "some", - }, - ) - - // pressure full - - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": memoryPressure.Full.Avg10, - "avg60": memoryPressure.Full.Avg60, - "avg300": memoryPressure.Full.Avg300, - }, - map[string]string{ - "resource": "memory", - "type": "full", - }, - ) - - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": ioPressure.Full.Avg10, - "avg60": ioPressure.Full.Avg60, - "avg300": ioPressure.Full.Avg300, - }, - map[string]string{ - "resource": "io", - "type": "full", - }, - ) + inputs.Add("psi", func() telegraf.Input { + return &Psi{} + }) } diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go new file mode 100644 index 0000000000000..777a5bd3f3ffd --- /dev/null +++ b/plugins/inputs/psi/psi_linux.go @@ -0,0 +1,162 @@ +package psi + +import ( + "fmt" + + "github.com/influxdata/telegraf" + "github.com/prometheus/procfs" +) + +// Gather Psi metrics +func (psi *Psi) Gather(acc telegraf.Accumulator) error { + cpuPressure, memoryPressure, ioPressure, err := psi.getPressureValues() + if err != nil { + return err + } + + psi.uploadPressure(cpuPressure, memoryPressure, ioPressure, acc) + return nil +} + +// getPressureValues - Get the pressure values from /proc/pressure/* +func (psi *Psi) getPressureValues() (cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, err error) { + var fs procfs.FS + fs, err = procfs.NewDefaultFS() + if err != nil { + err = fmt.Errorf("procfs not available: %w", err) + return + } + + cpuPressure, err = fs.PSIStatsForResource("cpu") + if err != nil { + err = fmt.Errorf("no CPU pressure found: %w", err) + return + } + + memoryPressure, err = fs.PSIStatsForResource("memory") + if err != nil { + err = fmt.Errorf("no memory pressure found: %w", err) + return + } + + ioPressure, err = fs.PSIStatsForResource("io") + if err != nil { + err = fmt.Errorf("no io pressure found: %w", err) + return + } + + return +} + +// uploadPressure Uploads all pressure value to corrosponding fields +func (psi *Psi) uploadPressure(cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, acc telegraf.Accumulator) { + + // pressureTotal some + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": cpuPressure.Some.Total, + }, + map[string]string{ + "resource": "cpu", + "type": "some", + }, + ) + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": memoryPressure.Some.Total, + }, + map[string]string{ + "resource": "memory", + "type": "some", + }, + ) + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": ioPressure.Some.Total, + }, + map[string]string{ + "resource": "io", + "type": "some", + }, + ) + + // pressureTotal full + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": memoryPressure.Full.Total, + }, + map[string]string{ + "resource": "memory", + "type": "full", + }, + ) + + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": ioPressure.Full.Total, + }, + map[string]string{ + "resource": "io", + "type": "full", + }, + ) + + // pressure some + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": cpuPressure.Some.Avg10, + "avg60": cpuPressure.Some.Avg60, + "avg300": cpuPressure.Some.Avg300, + }, + map[string]string{ + "resource": "cpu", + "type": "some", + }, + ) + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": memoryPressure.Some.Avg10, + "avg60": memoryPressure.Some.Avg60, + "avg300": memoryPressure.Some.Avg300, + }, + map[string]string{ + "resource": "memory", + "type": "some", + }, + ) + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": ioPressure.Some.Avg10, + "avg60": ioPressure.Some.Avg60, + "avg300": ioPressure.Some.Avg300, + }, + map[string]string{ + "resource": "io", + "type": "some", + }, + ) + + // pressure full + // NOTE: cpu.full is omitted because it is always zero + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": memoryPressure.Full.Avg10, + "avg60": memoryPressure.Full.Avg60, + "avg300": memoryPressure.Full.Avg300, + }, + map[string]string{ + "resource": "memory", + "type": "full", + }, + ) + + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": ioPressure.Full.Avg10, + "avg60": ioPressure.Full.Avg60, + "avg300": ioPressure.Full.Avg300, + }, + map[string]string{ + "resource": "io", + "type": "full", + }, + ) +} diff --git a/plugins/inputs/psi/psi_nonlinux.go b/plugins/inputs/psi/psi_nonlinux.go new file mode 100644 index 0000000000000..76e5b74c18096 --- /dev/null +++ b/plugins/inputs/psi/psi_nonlinux.go @@ -0,0 +1,10 @@ +//go:build !linux + +package psi + +import "github.com/influxdata/telegraf" + +func (psi *Psi) Gather(_ telegraf.Accumulator) error { + psi.Log.Warn("Pressure Stall Information is only supported on Linux") + return nil +} diff --git a/plugins/inputs/psi/sample.conf b/plugins/inputs/psi/sample.conf new file mode 100644 index 0000000000000..caa38b909d02f --- /dev/null +++ b/plugins/inputs/psi/sample.conf @@ -0,0 +1,4 @@ +# Read metrics about Pressure Stall Information (PSI) +# This plugin ONLY supports Linux v4.20+ +[[inputs.psi]] + # no configuration From df37b003afd447eaa0b41f78d08a8f7af04a0c61 Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 21:27:48 +0800 Subject: [PATCH 03/26] Cleanup psi_linux.go, add inputs/all/psi.go --- plugins/inputs/all/psi.go | 5 + plugins/inputs/psi/psi_linux.go | 184 ++++++++++---------------------- 2 files changed, 62 insertions(+), 127 deletions(-) create mode 100644 plugins/inputs/all/psi.go diff --git a/plugins/inputs/all/psi.go b/plugins/inputs/all/psi.go new file mode 100644 index 0000000000000..db54970f1d925 --- /dev/null +++ b/plugins/inputs/all/psi.go @@ -0,0 +1,5 @@ +//go:build !custom || inputs || inputs.psi + +package all + +import _ "github.com/influxdata/telegraf/plugins/inputs/psi" // register plugin diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index 777a5bd3f3ffd..dde0c6bd773ca 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -9,154 +9,84 @@ import ( // Gather Psi metrics func (psi *Psi) Gather(acc telegraf.Accumulator) error { - cpuPressure, memoryPressure, ioPressure, err := psi.getPressureValues() + pressures, err := psi.getPressureValues() if err != nil { return err } - - psi.uploadPressure(cpuPressure, memoryPressure, ioPressure, acc) + psi.uploadPressure(pressures, acc) return nil } // getPressureValues - Get the pressure values from /proc/pressure/* -func (psi *Psi) getPressureValues() (cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, err error) { +func (psi *Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { var fs procfs.FS fs, err = procfs.NewDefaultFS() if err != nil { - err = fmt.Errorf("procfs not available: %w", err) - return - } - - cpuPressure, err = fs.PSIStatsForResource("cpu") - if err != nil { - err = fmt.Errorf("no CPU pressure found: %w", err) - return + return nil, fmt.Errorf("procfs not available: %w", err) } - memoryPressure, err = fs.PSIStatsForResource("memory") - if err != nil { - err = fmt.Errorf("no memory pressure found: %w", err) - return - } - - ioPressure, err = fs.PSIStatsForResource("io") - if err != nil { - err = fmt.Errorf("no io pressure found: %w", err) - return + pressures = make(map[string]procfs.PSIStats) + for _, resource := range []string{"cpu", "memory", "io"} { + pressures[resource], err = fs.PSIStatsForResource(resource) + if err != nil { + return nil, fmt.Errorf("failed to read %s pressure: %w", resource, err) + } } - - return + return pressures, nil } // uploadPressure Uploads all pressure value to corrosponding fields -func (psi *Psi) uploadPressure(cpuPressure procfs.PSIStats, memoryPressure procfs.PSIStats, ioPressure procfs.PSIStats, acc telegraf.Accumulator) { - - // pressureTotal some - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": cpuPressure.Some.Total, - }, - map[string]string{ - "resource": "cpu", - "type": "some", - }, - ) - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": memoryPressure.Some.Total, - }, - map[string]string{ - "resource": "memory", - "type": "some", - }, - ) - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": ioPressure.Some.Total, - }, - map[string]string{ - "resource": "io", - "type": "some", +// NOTE: resource=cpu,type=full is omitted because it is always zero +func (psi *Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { + // pressureTotal type=some + for _, resource := range []string{"cpu", "memory", "io"} { + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": pressures[resource].Some.Total, }, - ) - - // pressureTotal full - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": memoryPressure.Full.Total, - }, - map[string]string{ - "resource": "memory", - "type": "full", - }, - ) - - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": ioPressure.Full.Total, - }, - map[string]string{ - "resource": "io", - "type": "full", - }, - ) - - // pressure some - - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": cpuPressure.Some.Avg10, - "avg60": cpuPressure.Some.Avg60, - "avg300": cpuPressure.Some.Avg300, - }, - map[string]string{ - "resource": "cpu", - "type": "some", - }, - ) - - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": memoryPressure.Some.Avg10, - "avg60": memoryPressure.Some.Avg60, - "avg300": memoryPressure.Some.Avg300, - }, - map[string]string{ - "resource": "memory", - "type": "some", - }, - ) + map[string]string{ + "resource": resource, + "type": "some", + }, + ) + } - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": ioPressure.Some.Avg10, - "avg60": ioPressure.Some.Avg60, - "avg300": ioPressure.Some.Avg300, - }, - map[string]string{ - "resource": "io", - "type": "some", + // pressureTotal type=full + for _, resource := range []string{"memory", "io"} { + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": pressures[resource].Full.Total, }, - ) - - // pressure full - // NOTE: cpu.full is omitted because it is always zero + map[string]string{ + "resource": resource, + "type": "full", + }, + ) + } - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": memoryPressure.Full.Avg10, - "avg60": memoryPressure.Full.Avg60, - "avg300": memoryPressure.Full.Avg300, - }, - map[string]string{ - "resource": "memory", - "type": "full", + // pressure type=some + for _, resource := range []string{"cpu", "memory", "io"} { + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": pressures[resource].Some.Avg10, + "avg60": pressures[resource].Some.Avg60, + "avg300": pressures[resource].Some.Avg300, }, - ) + map[string]string{ + "resource": resource, + "type": "some", + }, + ) + } - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": ioPressure.Full.Avg10, - "avg60": ioPressure.Full.Avg60, - "avg300": ioPressure.Full.Avg300, - }, - map[string]string{ - "resource": "io", - "type": "full", + // pressure type=full + for _, resource := range []string{"memory", "io"} { + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": pressures[resource].Full.Avg10, + "avg60": pressures[resource].Full.Avg60, + "avg300": pressures[resource].Full.Avg300, }, - ) + map[string]string{ + "resource": resource, + "type": "full", + }, + ) + } } From 800c09bda86f0b90ada989d24eb05d29cbc8ba06 Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 21:34:20 +0800 Subject: [PATCH 04/26] psi: Polish README --- plugins/inputs/psi/README.md | 61 ++++++++++++++++++++++++++++++---- plugins/inputs/psi/sample.conf | 2 +- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/plugins/inputs/psi/README.md b/plugins/inputs/psi/README.md index aa82bc4cd00f2..c2d9cba72c6e1 100644 --- a/plugins/inputs/psi/README.md +++ b/plugins/inputs/psi/README.md @@ -1,17 +1,66 @@ # Pressure Stall Information (PSI) Input Plugin -A plugin to gather resource pressure metrics from the Linux kernel. -Pressure Stall Information (PSI) is available at -"/proc/pressure/" -- cpu, memory and io. +A plugin to gather Pressure Stall Information from the Linux kernel from `/proc/pressure/{cpu,memory,io}`. + +Kernel version 4.20 or later is required. Examples: -/proc/pressure/cpu + +```shell +# /proc/pressure/cpu some avg10=1.53 avg60=1.87 avg300=1.73 total=1088168194 -/proc/pressure/memory +# /proc/pressure/memory some avg10=0.00 avg60=0.00 avg300=0.00 total=3463792 full avg10=0.00 avg60=0.00 avg300=0.00 total=1429641 -/proc/pressure/io +# /proc/pressure/io some avg10=0.00 avg60=0.00 avg300=0.00 total=68568296 full avg10=0.00 avg60=0.00 avg300=0.00 total=54982338 +``` + +## Global configuration options + +In addition to the plugin-specific configuration settings, plugins support +additional global and plugin configuration settings. These settings are used to +modify metrics, tags, and field or create aliases and configure ordering, etc. +See the [CONFIGURATION.md][CONFIGURATION.md] for more details. + +[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins + +## Configuration + +```toml @sample.conf +# Read metrics about Pressure Stall Information (PSI) +# Requires Linux kernel v4.20+ +[[inputs.psi]] + # no configuration +``` + +## Metrics + +- pressure + - tags: + - resource: cpu, memory, or io + - type: some or full + - fields: avg10, avg60, avg300 for 10-second, 1-minute, and 5-minute averages +- pressureTotal + - tags: same as pressure + - fields: total + +Note that the combination for `resource=cpu,type=full` is omitted because it is always zero. + +## Example Output + +```text +pressure,resource=cpu,type=some avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 +pressure,resource=memory,type=some avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 +pressure,resource=memory,type=full avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 +pressure,resource=io,type=some avg10=21.35,avg60=19.23,avg300=13.48 1700000000000000000 +pressure,resource=io,type=full avg10=21.26,avg60=19.10,avg300=13.39 1700000000000000000 +pressureTotal,resource=cpu,type=some total=657544125 1700000000000000000 +pressureTotal,resource=memory,type=some total=62167126 1700000000000000000 +pressureTotal,resource=memory,type=full total=60968885 1700000000000000000 +pressureTotal,resource=io,type=some total=6507666709 1700000000000000000 +pressureTotal,resource=io,type=full total=6399637024 1700000000000000000 +``` diff --git a/plugins/inputs/psi/sample.conf b/plugins/inputs/psi/sample.conf index caa38b909d02f..a789656271498 100644 --- a/plugins/inputs/psi/sample.conf +++ b/plugins/inputs/psi/sample.conf @@ -1,4 +1,4 @@ # Read metrics about Pressure Stall Information (PSI) -# This plugin ONLY supports Linux v4.20+ +# Requires Linux kernel v4.20+ [[inputs.psi]] # no configuration From a9e061a139bee6803ab3874333b39f1af6ed8561 Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 21:44:48 +0800 Subject: [PATCH 05/26] psi: Add unit test with go:build linux --- plugins/inputs/psi/psi_linux.go | 2 +- plugins/inputs/psi/psi_test.go | 75 +++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 plugins/inputs/psi/psi_test.go diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index dde0c6bd773ca..b9f1515b93104 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -37,7 +37,7 @@ func (psi *Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err e // uploadPressure Uploads all pressure value to corrosponding fields // NOTE: resource=cpu,type=full is omitted because it is always zero -func (psi *Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { +func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { // pressureTotal type=some for _, resource := range []string{"cpu", "memory", "io"} { acc.AddCounter("pressureTotal", map[string]interface{}{ diff --git a/plugins/inputs/psi/psi_test.go b/plugins/inputs/psi/psi_test.go new file mode 100644 index 0000000000000..04defc5f3e96f --- /dev/null +++ b/plugins/inputs/psi/psi_test.go @@ -0,0 +1,75 @@ +//go:build linux + +package psi + +import ( + "testing" + + "github.com/influxdata/telegraf/testutil" + "github.com/prometheus/procfs" + "github.com/stretchr/testify/require" +) + +func TestPSIStats(t *testing.T) { + var ( + psi *Psi + err error + acc testutil.Accumulator + ) + + mockPressure := &procfs.PSILine{ + Avg10: 10, + Avg60: 60, + Avg300: 300, + Total: 114514, + } + + mockPSIStats := procfs.PSIStats{ + Some: mockPressure, + Full: mockPressure, + } + + mockStats := map[string]procfs.PSIStats{ + "cpu": mockPSIStats, + "memory": mockPSIStats, + "io": mockPSIStats, + } + + err = psi.Gather(&acc) + require.NoError(t, err) + + pressureFields := map[string]interface{}{ + "avg10": float64(10), + "avg60": float64(60), + "avg300": float64(300), + } + pressureTotalFields := map[string]interface{}{ + "total": uint64(114514), + } + acc.ClearMetrics() + psi.uploadPressure(mockStats, &acc) + for _, typ := range []string{"some", "full"} { + for _, resource := range []string{"cpu", "memory", "io"} { + if resource == "cpu" && typ == "full" { + continue + } + + // "pressure" should contain what it should + acc.AssertContainsTaggedFields(t, "pressure", pressureFields, map[string]string{ + "resource": resource, + "type": typ, + }) + + // "pressure" should NOT contain a "total" field + acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureTotalFields, map[string]string{ + "resource": resource, + "type": typ, + }) + } + } + + acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureFields, map[string]string{ + "resource": "cpu", + "type": "full", + }) +} From 9f38df11bc0e26fa3f05b2b07eabb560fae4fc11 Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 21:56:10 +0800 Subject: [PATCH 06/26] inputs/psi: Add credits to gridscale/linux-psi-telegraf-plugin --- plugins/inputs/psi/README.md | 4 ++++ plugins/inputs/psi/psi_linux.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/inputs/psi/README.md b/plugins/inputs/psi/README.md index c2d9cba72c6e1..c2efd645b84aa 100644 --- a/plugins/inputs/psi/README.md +++ b/plugins/inputs/psi/README.md @@ -64,3 +64,7 @@ pressureTotal,resource=memory,type=full total=60968885 1700000000000000000 pressureTotal,resource=io,type=some total=6507666709 1700000000000000000 pressureTotal,resource=io,type=full total=6399637024 1700000000000000000 ``` + +## Credits + +Part of this plugin was derived from [gridscale/linux-psi-telegraf-plugin](https://github.com/gridscale/linux-psi-telegraf-plugin), available under the same MIT license. diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index b9f1515b93104..1beb3cfc90e6e 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -18,7 +18,7 @@ func (psi *Psi) Gather(acc telegraf.Accumulator) error { } // getPressureValues - Get the pressure values from /proc/pressure/* -func (psi *Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { +func (*Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { var fs procfs.FS fs, err = procfs.NewDefaultFS() if err != nil { From c4cb52b69f9bf8cc3c2f368e42717ebccb22638d Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 22:01:24 +0800 Subject: [PATCH 07/26] chore(README): Linting rules was a bit more stupid than I had previously anticipated --- plugins/inputs/psi/README.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/plugins/inputs/psi/README.md b/plugins/inputs/psi/README.md index c2efd645b84aa..2ab2f6b98f381 100644 --- a/plugins/inputs/psi/README.md +++ b/plugins/inputs/psi/README.md @@ -1,6 +1,7 @@ # Pressure Stall Information (PSI) Input Plugin -A plugin to gather Pressure Stall Information from the Linux kernel from `/proc/pressure/{cpu,memory,io}`. +A plugin to gather Pressure Stall Information from the Linux kernel +from `/proc/pressure/{cpu,memory,io}`. Kernel version 4.20 or later is required. @@ -48,23 +49,28 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - tags: same as pressure - fields: total -Note that the combination for `resource=cpu,type=full` is omitted because it is always zero. +Note that the combination for `resource=cpu,type=full` is omitted because it is +always zero. ## Example Output ```text -pressure,resource=cpu,type=some avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 +pressure,resource=cpu,type=some avg10=1.53,avg60=1.87,avg300=1.73 1700000000000000000 pressure,resource=memory,type=some avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 pressure,resource=memory,type=full avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 -pressure,resource=io,type=some avg10=21.35,avg60=19.23,avg300=13.48 1700000000000000000 -pressure,resource=io,type=full avg10=21.26,avg60=19.10,avg300=13.39 1700000000000000000 -pressureTotal,resource=cpu,type=some total=657544125 1700000000000000000 -pressureTotal,resource=memory,type=some total=62167126 1700000000000000000 -pressureTotal,resource=memory,type=full total=60968885 1700000000000000000 -pressureTotal,resource=io,type=some total=6507666709 1700000000000000000 -pressureTotal,resource=io,type=full total=6399637024 1700000000000000000 +pressure,resource=io,type=some avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 +pressure,resource=io,type=full avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 +pressureTotal,resource=cpu,type=some total=1088168194 1700000000000000000 +pressureTotal,resource=memory,type=some total=3463792 1700000000000000000 +pressureTotal,resource=memory,type=full total=1429641 1700000000000000000 +pressureTotal,resource=io,type=some total=68568296 1700000000000000000 +pressureTotal,resource=io,type=full total=54982338 1700000000000000000 ``` ## Credits -Part of this plugin was derived from [gridscale/linux-psi-telegraf-plugin](https://github.com/gridscale/linux-psi-telegraf-plugin), available under the same MIT license. +Part of this plugin was derived from +[gridscale/linux-psi-telegraf-plugin][gridscale/linux-psi-telegraf-plugin], +available under the same MIT license. + +[gridscale/linux-psi-telegraf-plugin]: https://github.com/gridscale/linux-psi-telegraf-plugin From 1becff8d84e9c18209de9fe6aeac910249bad577 Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 22:06:23 +0800 Subject: [PATCH 08/26] psi_linux: Merge type=some and type=full with a for loop --- plugins/inputs/psi/psi_linux.go | 76 +++++++++++++-------------------- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index 1beb3cfc90e6e..2017b11a401ae 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -38,55 +38,39 @@ func (*Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err error // uploadPressure Uploads all pressure value to corrosponding fields // NOTE: resource=cpu,type=full is omitted because it is always zero func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { - // pressureTotal type=some - for _, resource := range []string{"cpu", "memory", "io"} { - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": pressures[resource].Some.Total, - }, - map[string]string{ - "resource": resource, - "type": "some", - }, - ) - } - - // pressureTotal type=full - for _, resource := range []string{"memory", "io"} { - acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": pressures[resource].Full.Total, - }, - map[string]string{ - "resource": resource, - "type": "full", - }, - ) - } - - // pressure type=some - for _, resource := range []string{"cpu", "memory", "io"} { - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": pressures[resource].Some.Avg10, - "avg60": pressures[resource].Some.Avg60, - "avg300": pressures[resource].Some.Avg300, - }, - map[string]string{ - "resource": resource, - "type": "some", + // pressureTotal + for _, typ := range []string{"some", "full"} { + for _, resource := range []string{"cpu", "memory", "io"} { + if resource == "cpu" && typ == "full" { + continue + } + acc.AddCounter("pressureTotal", map[string]interface{}{ + "total": pressures[resource].Some.Total, }, - ) + map[string]string{ + "resource": resource, + "type": typ, + }, + ) + } } - // pressure type=full - for _, resource := range []string{"memory", "io"} { - acc.AddGauge("pressure", map[string]interface{}{ - "avg10": pressures[resource].Full.Avg10, - "avg60": pressures[resource].Full.Avg60, - "avg300": pressures[resource].Full.Avg300, - }, - map[string]string{ - "resource": resource, - "type": "full", + // pressure + for _, typ := range []string{"some", "full"} { + for _, resource := range []string{"cpu", "memory", "io"} { + if resource == "cpu" && typ == "full" { + continue + } + acc.AddGauge("pressure", map[string]interface{}{ + "avg10": pressures[resource].Some.Avg10, + "avg60": pressures[resource].Some.Avg60, + "avg300": pressures[resource].Some.Avg300, }, - ) + map[string]string{ + "resource": resource, + "type": typ, + }, + ) + } } } From 0e3042516a32009d4bc3953a3cbf9dea7dd92e48 Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 26 Dec 2023 22:43:26 +0800 Subject: [PATCH 09/26] psi: Add stub unit test for nonlinux --- plugins/inputs/psi/psi.go | 4 ++-- plugins/inputs/psi/psi_test_nonlinux.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 plugins/inputs/psi/psi_test_nonlinux.go diff --git a/plugins/inputs/psi/psi.go b/plugins/inputs/psi/psi.go index 1d2901c0a30b6..5192bcec18cb6 100644 --- a/plugins/inputs/psi/psi.go +++ b/plugins/inputs/psi/psi.go @@ -16,12 +16,12 @@ type Psi struct { var sampleConfig string // SampleConfig returns sample configuration for this plugin -func (psi *Psi) SampleConfig() string { +func (*Psi) SampleConfig() string { return sampleConfig } // Description returns the plugin description -func (psi *Psi) Description() string { +func (*Psi) Description() string { return "Gather Pressure Stall Information (PSI) from /proc/pressure/" } diff --git a/plugins/inputs/psi/psi_test_nonlinux.go b/plugins/inputs/psi/psi_test_nonlinux.go new file mode 100644 index 0000000000000..4de5d5cd23ee3 --- /dev/null +++ b/plugins/inputs/psi/psi_test_nonlinux.go @@ -0,0 +1,21 @@ +//go:build !linux + +package psi + +import ( + "testing" + + "github.com/influxdata/telegraf/testutil" + "github.com/stretchr/testify/require" +) + +func TestPSIStats(t *testing.T) { + var ( + psi *Psi + err error + acc testutil.Accumulator + ) + + err = psi.Gather(&acc) + require.NoError(t, err) +} From aab6c83e7a181e53a205946a64b8c81d2293c0d1 Mon Sep 17 00:00:00 2001 From: iBug Date: Wed, 27 Dec 2023 16:57:24 +0800 Subject: [PATCH 10/26] fix: (*procfs.PSILine).Full was not used at all --- plugins/inputs/psi/psi_linux.go | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index 2017b11a401ae..458f9c4111bee 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -44,8 +44,17 @@ func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Ac if resource == "cpu" && typ == "full" { continue } + + var stat *procfs.PSILine + switch typ { + case "some": + stat = pressures[resource].Some + case "full": + stat = pressures[resource].Full + } + acc.AddCounter("pressureTotal", map[string]interface{}{ - "total": pressures[resource].Some.Total, + "total": stat.Total, }, map[string]string{ "resource": resource, @@ -61,10 +70,19 @@ func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Ac if resource == "cpu" && typ == "full" { continue } + + var stat *procfs.PSILine + switch typ { + case "some": + stat = pressures[resource].Some + case "full": + stat = pressures[resource].Full + } + acc.AddGauge("pressure", map[string]interface{}{ - "avg10": pressures[resource].Some.Avg10, - "avg60": pressures[resource].Some.Avg60, - "avg300": pressures[resource].Some.Avg300, + "avg10": stat.Avg10, + "avg60": stat.Avg60, + "avg300": stat.Avg300, }, map[string]string{ "resource": resource, From a1ab1aa92677970f06a7c2317048173bb3158b6a Mon Sep 17 00:00:00 2001 From: iBug Date: Wed, 27 Dec 2023 17:12:41 +0800 Subject: [PATCH 11/26] psi_linux: Merge two loops with same structure --- plugins/inputs/psi/psi_linux.go | 39 ++++++++------------------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index 458f9c4111bee..395032c7db01e 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -38,13 +38,17 @@ func (*Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err error // uploadPressure Uploads all pressure value to corrosponding fields // NOTE: resource=cpu,type=full is omitted because it is always zero func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { - // pressureTotal for _, typ := range []string{"some", "full"} { for _, resource := range []string{"cpu", "memory", "io"} { if resource == "cpu" && typ == "full" { continue } + tags := map[string]string{ + "resource": resource, + "type": typ, + } + var stat *procfs.PSILine switch typ { case "some": @@ -53,42 +57,17 @@ func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Ac stat = pressures[resource].Full } + // pressureTotal acc.AddCounter("pressureTotal", map[string]interface{}{ "total": stat.Total, - }, - map[string]string{ - "resource": resource, - "type": typ, - }, - ) - } - } - - // pressure - for _, typ := range []string{"some", "full"} { - for _, resource := range []string{"cpu", "memory", "io"} { - if resource == "cpu" && typ == "full" { - continue - } - - var stat *procfs.PSILine - switch typ { - case "some": - stat = pressures[resource].Some - case "full": - stat = pressures[resource].Full - } + }, tags) + // pressure acc.AddGauge("pressure", map[string]interface{}{ "avg10": stat.Avg10, "avg60": stat.Avg60, "avg300": stat.Avg300, - }, - map[string]string{ - "resource": resource, - "type": typ, - }, - ) + }, tags) } } } From 9107636909e263b1707f2c7fc2fe4d4d31a38901 Mon Sep 17 00:00:00 2001 From: iBug Date: Wed, 27 Dec 2023 17:51:21 +0800 Subject: [PATCH 12/26] psi_test: Add supporting tests for aab6c83e7a181e53a205946a64b8c81d2293c0d1 --- plugins/inputs/psi/psi_test.go | 62 ++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/plugins/inputs/psi/psi_test.go b/plugins/inputs/psi/psi_test.go index 04defc5f3e96f..d5f5e4db9a4d9 100644 --- a/plugins/inputs/psi/psi_test.go +++ b/plugins/inputs/psi/psi_test.go @@ -17,18 +17,22 @@ func TestPSIStats(t *testing.T) { acc testutil.Accumulator ) - mockPressure := &procfs.PSILine{ + mockPressureSome := &procfs.PSILine{ Avg10: 10, Avg60: 60, Avg300: 300, Total: 114514, } - + mockPressureFull := &procfs.PSILine{ + Avg10: 1, + Avg60: 6, + Avg300: 30, + Total: 11451, + } mockPSIStats := procfs.PSIStats{ - Some: mockPressure, - Full: mockPressure, + Some: mockPressureSome, + Full: mockPressureFull, } - mockStats := map[string]procfs.PSIStats{ "cpu": mockPSIStats, "memory": mockPSIStats, @@ -38,14 +42,27 @@ func TestPSIStats(t *testing.T) { err = psi.Gather(&acc) require.NoError(t, err) - pressureFields := map[string]interface{}{ - "avg10": float64(10), - "avg60": float64(60), - "avg300": float64(300), + pressureFields := map[string]map[string]interface{}{ + "some": { + "avg10": float64(10), + "avg60": float64(60), + "avg300": float64(300), + }, + "full": { + "avg10": float64(1), + "avg60": float64(6), + "avg300": float64(30), + }, } - pressureTotalFields := map[string]interface{}{ - "total": uint64(114514), + pressureTotalFields := map[string]map[string]interface{}{ + "some": { + "total": uint64(114514), + }, + "full": { + "total": uint64(11451), + }, } + acc.ClearMetrics() psi.uploadPressure(mockStats, &acc) for _, typ := range []string{"some", "full"} { @@ -54,22 +71,25 @@ func TestPSIStats(t *testing.T) { continue } - // "pressure" should contain what it should - acc.AssertContainsTaggedFields(t, "pressure", pressureFields, map[string]string{ + tags := map[string]string{ "resource": resource, "type": typ, - }) + } - // "pressure" should NOT contain a "total" field - acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureTotalFields, map[string]string{ - "resource": resource, - "type": typ, - }) + acc.AssertContainsTaggedFields(t, "pressure", pressureFields[typ], tags) + acc.AssertContainsTaggedFields(t, "pressureTotal", pressureTotalFields[typ], tags) + + // "pressure" and "pressureTotal" should contain disjoint set of fields + acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureTotalFields[typ], tags) + acc.AssertDoesNotContainsTaggedFields(t, "pressureTotal", pressureFields[typ], tags) } } - acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureFields, map[string]string{ + // The combination "resource=cpu,type=full" should NOT appear anywhere + forbiddenTags := map[string]string{ "resource": "cpu", "type": "full", - }) + } + acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureFields["full"], forbiddenTags) + acc.AssertDoesNotContainsTaggedFields(t, "pressureTotal", pressureTotalFields["full"], forbiddenTags) } From 90335b666f0603dfa2f20bb184e6ab11b388050b Mon Sep 17 00:00:00 2001 From: iBug Date: Tue, 2 Jan 2024 23:32:05 +0800 Subject: [PATCH 13/26] psi: Merge pressure and pressureTotal into one series --- plugins/inputs/psi/README.md | 10 +++++----- plugins/inputs/psi/psi_linux.go | 11 +++++++---- plugins/inputs/psi/psi_test.go | 9 +++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/inputs/psi/README.md b/plugins/inputs/psi/README.md index 2ab2f6b98f381..1f868d75874af 100644 --- a/plugins/inputs/psi/README.md +++ b/plugins/inputs/psi/README.md @@ -60,11 +60,11 @@ pressure,resource=memory,type=some avg10=0.00,avg60=0.00,avg300=0.00 17000000000 pressure,resource=memory,type=full avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 pressure,resource=io,type=some avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 pressure,resource=io,type=full avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 -pressureTotal,resource=cpu,type=some total=1088168194 1700000000000000000 -pressureTotal,resource=memory,type=some total=3463792 1700000000000000000 -pressureTotal,resource=memory,type=full total=1429641 1700000000000000000 -pressureTotal,resource=io,type=some total=68568296 1700000000000000000 -pressureTotal,resource=io,type=full total=54982338 1700000000000000000 +pressure,resource=cpu,type=some total=1088168194i 1700000000000000000 +pressure,resource=memory,type=some total=3463792i 1700000000000000000 +pressure,resource=memory,type=full total=1429641i 1700000000000000000 +pressure,resource=io,type=some total=68568296i 1700000000000000000 +pressure,resource=io,type=full total=54982338i 1700000000000000000 ``` ## Credits diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index 395032c7db01e..1e3d05cc2e390 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -2,6 +2,7 @@ package psi import ( "fmt" + "time" "github.com/influxdata/telegraf" "github.com/prometheus/procfs" @@ -57,17 +58,19 @@ func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Ac stat = pressures[resource].Full } - // pressureTotal - acc.AddCounter("pressureTotal", map[string]interface{}{ + now := time.Now() + + // pressure + acc.AddCounter("pressure", map[string]interface{}{ "total": stat.Total, - }, tags) + }, tags, now) // pressure acc.AddGauge("pressure", map[string]interface{}{ "avg10": stat.Avg10, "avg60": stat.Avg60, "avg300": stat.Avg300, - }, tags) + }, tags, now) } } } diff --git a/plugins/inputs/psi/psi_test.go b/plugins/inputs/psi/psi_test.go index d5f5e4db9a4d9..889916ec7e452 100644 --- a/plugins/inputs/psi/psi_test.go +++ b/plugins/inputs/psi/psi_test.go @@ -42,6 +42,7 @@ func TestPSIStats(t *testing.T) { err = psi.Gather(&acc) require.NoError(t, err) + // separate fields for gauges and counters pressureFields := map[string]map[string]interface{}{ "some": { "avg10": float64(10), @@ -77,11 +78,7 @@ func TestPSIStats(t *testing.T) { } acc.AssertContainsTaggedFields(t, "pressure", pressureFields[typ], tags) - acc.AssertContainsTaggedFields(t, "pressureTotal", pressureTotalFields[typ], tags) - - // "pressure" and "pressureTotal" should contain disjoint set of fields - acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureTotalFields[typ], tags) - acc.AssertDoesNotContainsTaggedFields(t, "pressureTotal", pressureFields[typ], tags) + acc.AssertContainsTaggedFields(t, "pressure", pressureTotalFields[typ], tags) } } @@ -91,5 +88,5 @@ func TestPSIStats(t *testing.T) { "type": "full", } acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureFields["full"], forbiddenTags) - acc.AssertDoesNotContainsTaggedFields(t, "pressureTotal", pressureTotalFields["full"], forbiddenTags) + acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureTotalFields["full"], forbiddenTags) } From 4e6cae0691fd185f620b7aaf988df07c981b79f7 Mon Sep 17 00:00:00 2001 From: iBug Date: Thu, 4 Jan 2024 18:28:40 +0800 Subject: [PATCH 14/26] inputs/psi: Start migrating PSI code to inputs/kernel --- plugins/inputs/kernel/README.md | 31 ++++++++++++++++++++++++++++++- plugins/inputs/kernel/kernel.go | 7 +++++++ plugins/inputs/kernel/sample.conf | 1 + plugins/inputs/psi/README.md | 5 +---- plugins/inputs/psi/psi_linux.go | 4 ---- 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/plugins/inputs/kernel/README.md b/plugins/inputs/kernel/README.md index 2ea010bc22a01..4b5bc09670a5e 100644 --- a/plugins/inputs/kernel/README.md +++ b/plugins/inputs/kernel/README.md @@ -11,7 +11,6 @@ The metrics are documented in `man proc` under the `/proc/stat` section. The metrics are documented in `man 4 random` under the `/proc/stat` section. ```text - /proc/sys/kernel/random/entropy_avail Contains the value of available entropy @@ -63,6 +62,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. ## Additional gather options ## Possible options include: ## * ksm - kernel same-page merging + ## * psi - pressure stall information # collect = [] ``` @@ -91,11 +91,40 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - ksm_stable_node_dups (integer, number of duplicated KSM pages, `stable_node_dups`) - ksm_use_zero_pages (integer, whether empty pages should be treated specially, `use_zero_pages`) +- pressure (if `psi` is included in `collect`) + - tags: + - resource: cpu, memory, or io + - type: some or full + - fields: avg10, avg60, avg300, total + ## Example Output +Default config: + ```text kernel boot_time=1690487872i,context_switches=321398652i,entropy_avail=256i,interrupts=141868628i,processes_forked=946492i 1691339564000000000 +``` + +If `ksm` is included in `collect`: +``` kernel boot_time=1690487872i,context_switches=321252729i,entropy_avail=256i,interrupts=141783427i,ksm_full_scans=0i,ksm_max_page_sharing=256i,ksm_merge_across_nodes=1i,ksm_pages_shared=0i,ksm_pages_sharing=0i,ksm_pages_to_scan=100i,ksm_pages_unshared=0i,ksm_pages_volatile=0i,ksm_run=0i,ksm_sleep_millisecs=20i,ksm_stable_node_chains=0i,ksm_stable_node_chains_prune_millisecs=2000i,ksm_stable_node_dups=0i,ksm_use_zero_pages=0i,processes_forked=946467i 1691339522000000000 +``` + +If `psi` is included in `collect`: +```text +pressure,resource=cpu,type=some avg10=1.53,avg60=1.87,avg300=1.73 1700000000000000000 +pressure,resource=memory,type=some avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 +pressure,resource=memory,type=full avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 +pressure,resource=io,type=some avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 +pressure,resource=io,type=full avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 +pressure,resource=cpu,type=some total=1088168194i 1700000000000000000 +pressure,resource=memory,type=some total=3463792i 1700000000000000000 +pressure,resource=memory,type=full total=1429641i 1700000000000000000 +pressure,resource=io,type=some total=68568296i 1700000000000000000 +pressure,resource=io,type=full total=54982338i 1700000000000000000 ``` + +Note that the combination for `resource=cpu,type=full` is omitted because it is +always zero. diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index 9e98bc6e0881f..d7abc1d414a89 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -34,6 +34,7 @@ type Kernel struct { statFile string entropyStatFile string ksmStatsDir string + psiDir string } func (k *Kernel) Init() error { @@ -48,6 +49,12 @@ func (k *Kernel) Init() error { return fmt.Errorf("directory %q does not exist. Is KSM enabled in this kernel?", k.ksmStatsDir) } } + if k.optCollect["psi"] { + if _, err := os.Stat(k.psiDir); os.IsNotExist(err) { + // psi probably not supported in the kernel, bail out early + return fmt.Errorf("directory %q does not exist. Is PSI enabled in this kernel?", k.psiDir) + } + } return nil } diff --git a/plugins/inputs/kernel/sample.conf b/plugins/inputs/kernel/sample.conf index bdc3fc053e3c7..d848024360b0c 100644 --- a/plugins/inputs/kernel/sample.conf +++ b/plugins/inputs/kernel/sample.conf @@ -4,4 +4,5 @@ ## Additional gather options ## Possible options include: ## * ksm - kernel same-page merging + ## * psi - pressure stall information # collect = [] diff --git a/plugins/inputs/psi/README.md b/plugins/inputs/psi/README.md index 1f868d75874af..03f3a80ff154b 100644 --- a/plugins/inputs/psi/README.md +++ b/plugins/inputs/psi/README.md @@ -44,10 +44,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - tags: - resource: cpu, memory, or io - type: some or full - - fields: avg10, avg60, avg300 for 10-second, 1-minute, and 5-minute averages -- pressureTotal - - tags: same as pressure - - fields: total + - fields: avg10, avg60, avg300, total Note that the combination for `resource=cpu,type=full` is omitted because it is always zero. diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/psi/psi_linux.go index 1e3d05cc2e390..a27280e6e9160 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/psi/psi_linux.go @@ -59,13 +59,9 @@ func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Ac } now := time.Now() - - // pressure acc.AddCounter("pressure", map[string]interface{}{ "total": stat.Total, }, tags, now) - - // pressure acc.AddGauge("pressure", map[string]interface{}{ "avg10": stat.Avg10, "avg60": stat.Avg60, From 47626a02571c883b3adabfc54c2a99746bacd4d6 Mon Sep 17 00:00:00 2001 From: iBug Date: Thu, 4 Jan 2024 18:41:00 +0800 Subject: [PATCH 15/26] Move code from inputs/psi to inputs/kernel --- plugins/inputs/all/psi.go | 5 -- plugins/inputs/kernel/README.md | 18 ++++- plugins/inputs/kernel/kernel.go | 6 ++ plugins/inputs/{psi => kernel}/psi_linux.go | 12 ++-- plugins/inputs/{psi => kernel}/psi_test.go | 8 +-- plugins/inputs/psi/README.md | 73 --------------------- plugins/inputs/psi/psi.go | 32 --------- plugins/inputs/psi/psi_nonlinux.go | 10 --- plugins/inputs/psi/psi_test_nonlinux.go | 21 ------ plugins/inputs/psi/sample.conf | 4 -- 10 files changed, 33 insertions(+), 156 deletions(-) delete mode 100644 plugins/inputs/all/psi.go rename plugins/inputs/{psi => kernel}/psi_linux.go (81%) rename plugins/inputs/{psi => kernel}/psi_test.go (95%) delete mode 100644 plugins/inputs/psi/README.md delete mode 100644 plugins/inputs/psi/psi.go delete mode 100644 plugins/inputs/psi/psi_nonlinux.go delete mode 100644 plugins/inputs/psi/psi_test_nonlinux.go delete mode 100644 plugins/inputs/psi/sample.conf diff --git a/plugins/inputs/all/psi.go b/plugins/inputs/all/psi.go deleted file mode 100644 index db54970f1d925..0000000000000 --- a/plugins/inputs/all/psi.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !custom || inputs || inputs.psi - -package all - -import _ "github.com/influxdata/telegraf/plugins/inputs/psi" // register plugin diff --git a/plugins/inputs/kernel/README.md b/plugins/inputs/kernel/README.md index 4b5bc09670a5e..450d506fb8566 100644 --- a/plugins/inputs/kernel/README.md +++ b/plugins/inputs/kernel/README.md @@ -5,7 +5,7 @@ This plugin is only available on Linux. The kernel plugin gathers info about the kernel that doesn't fit into other plugins. In general, it is the statistics available in `/proc/stat` that are not covered by other plugins as well as the value of -`/proc/sys/kernel/random/entropy_avail` and optionally, Kernel Samepage Merging. +`/proc/sys/kernel/random/entropy_avail` and optionally, Kernel Samepage Merging and Pressure Stall Information. The metrics are documented in `man proc` under the `/proc/stat` section. The metrics are documented in `man 4 random` under the `/proc/stat` section. @@ -41,8 +41,24 @@ Number of forks since boot. Kernel Samepage Merging is generally documented in [kernel documentation][1] and the available metrics exposed via sysfs are documented in [admin guide][2] +Pressure Stall Information is documented in [kernel documentation][3]. Kernel version 4.20 or later is required. Examples of PSI: + +```shell +# /proc/pressure/cpu +some avg10=1.53 avg60=1.87 avg300=1.73 total=1088168194 + +# /proc/pressure/memory +some avg10=0.00 avg60=0.00 avg300=0.00 total=3463792 +full avg10=0.00 avg60=0.00 avg300=0.00 total=1429641 + +# /proc/pressure/io +some avg10=0.00 avg60=0.00 avg300=0.00 total=68568296 +full avg10=0.00 avg60=0.00 avg300=0.00 total=54982338 +``` + [1]: https://www.kernel.org/doc/html/latest/mm/ksm.html [2]: https://www.kernel.org/doc/html/latest/admin-guide/mm/ksm.html#ksm-daemon-sysfs-interface +[3]: https://www.kernel.org/doc/html/latest/accounting/psi.html ## Global configuration options diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index d7abc1d414a89..a1fa3eafed57d 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -152,6 +152,12 @@ func (k *Kernel) Gather(acc telegraf.Accumulator) error { } acc.AddCounter("kernel", fields, map[string]string{}) + if k.optCollect["psi"] { + if err := k.gatherPressure(acc); err != nil { + return err + } + } + return nil } diff --git a/plugins/inputs/psi/psi_linux.go b/plugins/inputs/kernel/psi_linux.go similarity index 81% rename from plugins/inputs/psi/psi_linux.go rename to plugins/inputs/kernel/psi_linux.go index a27280e6e9160..4b33f1b404ffd 100644 --- a/plugins/inputs/psi/psi_linux.go +++ b/plugins/inputs/kernel/psi_linux.go @@ -1,4 +1,4 @@ -package psi +package kernel import ( "fmt" @@ -9,17 +9,17 @@ import ( ) // Gather Psi metrics -func (psi *Psi) Gather(acc telegraf.Accumulator) error { - pressures, err := psi.getPressureValues() +func (k *Kernel) gatherPressure(acc telegraf.Accumulator) error { + pressures, err := k.getPressureValues() if err != nil { return err } - psi.uploadPressure(pressures, acc) + k.uploadPressure(pressures, acc) return nil } // getPressureValues - Get the pressure values from /proc/pressure/* -func (*Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { +func (*Kernel) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { var fs procfs.FS fs, err = procfs.NewDefaultFS() if err != nil { @@ -38,7 +38,7 @@ func (*Psi) getPressureValues() (pressures map[string]procfs.PSIStats, err error // uploadPressure Uploads all pressure value to corrosponding fields // NOTE: resource=cpu,type=full is omitted because it is always zero -func (*Psi) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { +func (*Kernel) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { for _, typ := range []string{"some", "full"} { for _, resource := range []string{"cpu", "memory", "io"} { if resource == "cpu" && typ == "full" { diff --git a/plugins/inputs/psi/psi_test.go b/plugins/inputs/kernel/psi_test.go similarity index 95% rename from plugins/inputs/psi/psi_test.go rename to plugins/inputs/kernel/psi_test.go index 889916ec7e452..44cffc6ee9f54 100644 --- a/plugins/inputs/psi/psi_test.go +++ b/plugins/inputs/kernel/psi_test.go @@ -1,6 +1,6 @@ //go:build linux -package psi +package kernel import ( "testing" @@ -12,7 +12,7 @@ import ( func TestPSIStats(t *testing.T) { var ( - psi *Psi + k *Kernel err error acc testutil.Accumulator ) @@ -39,7 +39,7 @@ func TestPSIStats(t *testing.T) { "io": mockPSIStats, } - err = psi.Gather(&acc) + err = k.gatherPressure(&acc) require.NoError(t, err) // separate fields for gauges and counters @@ -65,7 +65,7 @@ func TestPSIStats(t *testing.T) { } acc.ClearMetrics() - psi.uploadPressure(mockStats, &acc) + k.uploadPressure(mockStats, &acc) for _, typ := range []string{"some", "full"} { for _, resource := range []string{"cpu", "memory", "io"} { if resource == "cpu" && typ == "full" { diff --git a/plugins/inputs/psi/README.md b/plugins/inputs/psi/README.md deleted file mode 100644 index 03f3a80ff154b..0000000000000 --- a/plugins/inputs/psi/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Pressure Stall Information (PSI) Input Plugin - -A plugin to gather Pressure Stall Information from the Linux kernel -from `/proc/pressure/{cpu,memory,io}`. - -Kernel version 4.20 or later is required. - -Examples: - -```shell -# /proc/pressure/cpu -some avg10=1.53 avg60=1.87 avg300=1.73 total=1088168194 - -# /proc/pressure/memory -some avg10=0.00 avg60=0.00 avg300=0.00 total=3463792 -full avg10=0.00 avg60=0.00 avg300=0.00 total=1429641 - -# /proc/pressure/io -some avg10=0.00 avg60=0.00 avg300=0.00 total=68568296 -full avg10=0.00 avg60=0.00 avg300=0.00 total=54982338 -``` - -## Global configuration options - -In addition to the plugin-specific configuration settings, plugins support -additional global and plugin configuration settings. These settings are used to -modify metrics, tags, and field or create aliases and configure ordering, etc. -See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - -[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins - -## Configuration - -```toml @sample.conf -# Read metrics about Pressure Stall Information (PSI) -# Requires Linux kernel v4.20+ -[[inputs.psi]] - # no configuration -``` - -## Metrics - -- pressure - - tags: - - resource: cpu, memory, or io - - type: some or full - - fields: avg10, avg60, avg300, total - -Note that the combination for `resource=cpu,type=full` is omitted because it is -always zero. - -## Example Output - -```text -pressure,resource=cpu,type=some avg10=1.53,avg60=1.87,avg300=1.73 1700000000000000000 -pressure,resource=memory,type=some avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 -pressure,resource=memory,type=full avg10=0.00,avg60=0.00,avg300=0.00 1700000000000000000 -pressure,resource=io,type=some avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 -pressure,resource=io,type=full avg10=0.0,avg60=0.0,avg300=0.0 1700000000000000000 -pressure,resource=cpu,type=some total=1088168194i 1700000000000000000 -pressure,resource=memory,type=some total=3463792i 1700000000000000000 -pressure,resource=memory,type=full total=1429641i 1700000000000000000 -pressure,resource=io,type=some total=68568296i 1700000000000000000 -pressure,resource=io,type=full total=54982338i 1700000000000000000 -``` - -## Credits - -Part of this plugin was derived from -[gridscale/linux-psi-telegraf-plugin][gridscale/linux-psi-telegraf-plugin], -available under the same MIT license. - -[gridscale/linux-psi-telegraf-plugin]: https://github.com/gridscale/linux-psi-telegraf-plugin diff --git a/plugins/inputs/psi/psi.go b/plugins/inputs/psi/psi.go deleted file mode 100644 index 5192bcec18cb6..0000000000000 --- a/plugins/inputs/psi/psi.go +++ /dev/null @@ -1,32 +0,0 @@ -package psi - -import ( - _ "embed" - - "github.com/influxdata/telegraf" - "github.com/influxdata/telegraf/plugins/inputs" -) - -// Psi - Plugins main structure -type Psi struct { - Log telegraf.Logger `toml:"-"` -} - -//go:embed sample.conf -var sampleConfig string - -// SampleConfig returns sample configuration for this plugin -func (*Psi) SampleConfig() string { - return sampleConfig -} - -// Description returns the plugin description -func (*Psi) Description() string { - return "Gather Pressure Stall Information (PSI) from /proc/pressure/" -} - -func init() { - inputs.Add("psi", func() telegraf.Input { - return &Psi{} - }) -} diff --git a/plugins/inputs/psi/psi_nonlinux.go b/plugins/inputs/psi/psi_nonlinux.go deleted file mode 100644 index 76e5b74c18096..0000000000000 --- a/plugins/inputs/psi/psi_nonlinux.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !linux - -package psi - -import "github.com/influxdata/telegraf" - -func (psi *Psi) Gather(_ telegraf.Accumulator) error { - psi.Log.Warn("Pressure Stall Information is only supported on Linux") - return nil -} diff --git a/plugins/inputs/psi/psi_test_nonlinux.go b/plugins/inputs/psi/psi_test_nonlinux.go deleted file mode 100644 index 4de5d5cd23ee3..0000000000000 --- a/plugins/inputs/psi/psi_test_nonlinux.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build !linux - -package psi - -import ( - "testing" - - "github.com/influxdata/telegraf/testutil" - "github.com/stretchr/testify/require" -) - -func TestPSIStats(t *testing.T) { - var ( - psi *Psi - err error - acc testutil.Accumulator - ) - - err = psi.Gather(&acc) - require.NoError(t, err) -} diff --git a/plugins/inputs/psi/sample.conf b/plugins/inputs/psi/sample.conf deleted file mode 100644 index a789656271498..0000000000000 --- a/plugins/inputs/psi/sample.conf +++ /dev/null @@ -1,4 +0,0 @@ -# Read metrics about Pressure Stall Information (PSI) -# Requires Linux kernel v4.20+ -[[inputs.psi]] - # no configuration From c9707550f97e56f9722768e2731f7e2fba01d53b Mon Sep 17 00:00:00 2001 From: iBug Date: Thu, 4 Jan 2024 18:44:03 +0800 Subject: [PATCH 16/26] inputs/kernel: Fix documentation and formatting --- plugins/inputs/kernel/README.md | 10 +++++----- plugins/inputs/kernel/kernel.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/inputs/kernel/README.md b/plugins/inputs/kernel/README.md index 450d506fb8566..de07e9f7d97d4 100644 --- a/plugins/inputs/kernel/README.md +++ b/plugins/inputs/kernel/README.md @@ -7,8 +7,7 @@ plugins. In general, it is the statistics available in `/proc/stat` that are not covered by other plugins as well as the value of `/proc/sys/kernel/random/entropy_avail` and optionally, Kernel Samepage Merging and Pressure Stall Information. -The metrics are documented in `man proc` under the `/proc/stat` section. -The metrics are documented in `man 4 random` under the `/proc/stat` section. +The metrics are documented in `man 5 proc` under the `/proc/stat` section, as well as `man 4 random` under the `/proc interfaces` section (for `entropy_avail`). ```text /proc/sys/kernel/random/entropy_avail @@ -41,7 +40,7 @@ Number of forks since boot. Kernel Samepage Merging is generally documented in [kernel documentation][1] and the available metrics exposed via sysfs are documented in [admin guide][2] -Pressure Stall Information is documented in [kernel documentation][3]. Kernel version 4.20 or later is required. Examples of PSI: +Pressure Stall Information is exposed through `/proc/pressure` and is documented in [kernel documentation][3]. Kernel version 4.20 or later is required. Examples of PSI: ```shell # /proc/pressure/cpu @@ -111,7 +110,8 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - tags: - resource: cpu, memory, or io - type: some or full - - fields: avg10, avg60, avg300, total + - floating-point fields: avg10, avg60, avg300 + - integer fields: total ## Example Output @@ -123,7 +123,7 @@ kernel boot_time=1690487872i,context_switches=321398652i,entropy_avail=256i,inte If `ksm` is included in `collect`: -``` +```text kernel boot_time=1690487872i,context_switches=321252729i,entropy_avail=256i,interrupts=141783427i,ksm_full_scans=0i,ksm_max_page_sharing=256i,ksm_merge_across_nodes=1i,ksm_pages_shared=0i,ksm_pages_sharing=0i,ksm_pages_to_scan=100i,ksm_pages_unshared=0i,ksm_pages_volatile=0i,ksm_run=0i,ksm_sleep_millisecs=20i,ksm_stable_node_chains=0i,ksm_stable_node_chains_prune_millisecs=2000i,ksm_stable_node_dups=0i,ksm_use_zero_pages=0i,processes_forked=946467i 1691339522000000000 ``` diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index a1fa3eafed57d..1c3ed192315ec 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -163,7 +163,7 @@ func (k *Kernel) Gather(acc telegraf.Accumulator) error { func (k *Kernel) getProcValueBytes(path string) ([]byte, error) { if _, err := os.Stat(path); os.IsNotExist(err) { - return nil, fmt.Errorf("Path %q does not exist", path) + return nil, fmt.Errorf("path %q does not exist", path) } else if err != nil { return nil, err } From 69fe9a4515e81a6e36631276c386d06ff3dfca5f Mon Sep 17 00:00:00 2001 From: iBug Date: Thu, 4 Jan 2024 18:54:53 +0800 Subject: [PATCH 17/26] inputs/kernel: Fix README long lines --- plugins/inputs/kernel/README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/plugins/inputs/kernel/README.md b/plugins/inputs/kernel/README.md index de07e9f7d97d4..8b53efa3fc688 100644 --- a/plugins/inputs/kernel/README.md +++ b/plugins/inputs/kernel/README.md @@ -5,9 +5,12 @@ This plugin is only available on Linux. The kernel plugin gathers info about the kernel that doesn't fit into other plugins. In general, it is the statistics available in `/proc/stat` that are not covered by other plugins as well as the value of -`/proc/sys/kernel/random/entropy_avail` and optionally, Kernel Samepage Merging and Pressure Stall Information. +`/proc/sys/kernel/random/entropy_avail` and optionally, Kernel Samepage Merging +and Pressure Stall Information. -The metrics are documented in `man 5 proc` under the `/proc/stat` section, as well as `man 4 random` under the `/proc interfaces` section (for `entropy_avail`). +The metrics are documented in `man 5 proc` under the `/proc/stat` section, as +well as `man 4 random` under the `/proc interfaces` section +(for `entropy_avail`). ```text /proc/sys/kernel/random/entropy_avail @@ -38,9 +41,11 @@ Number of forks since boot. ``` Kernel Samepage Merging is generally documented in [kernel documentation][1] and -the available metrics exposed via sysfs are documented in [admin guide][2] +the available metrics exposed via sysfs are documented in [admin guide][2]. -Pressure Stall Information is exposed through `/proc/pressure` and is documented in [kernel documentation][3]. Kernel version 4.20 or later is required. Examples of PSI: +Pressure Stall Information is exposed through `/proc/pressure` and is documented +in [kernel documentation][3]. Kernel version 4.20 or later is required. +Examples of PSI: ```shell # /proc/pressure/cpu From bcad0642558cc1b2cdf6c6c2a5744377e1900d95 Mon Sep 17 00:00:00 2001 From: iBug Date: Thu, 4 Jan 2024 18:58:26 +0800 Subject: [PATCH 18/26] inputs/kernel: Add initializer value for k.psiDir --- plugins/inputs/kernel/kernel.go | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index 1c3ed192315ec..c4197b83f58aa 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -196,6 +196,7 @@ func init() { statFile: "/proc/stat", entropyStatFile: "/proc/sys/kernel/random/entropy_avail", ksmStatsDir: "/sys/kernel/mm/ksm", + psiDir: "/proc/pressure", } }) } From 5da3e6c43112ab1f98ef84016896b19c57553dfd Mon Sep 17 00:00:00 2001 From: iBug Date: Thu, 4 Jan 2024 19:00:01 +0800 Subject: [PATCH 19/26] inputs/kernel: Rename psi_linux.go to psi.go --- plugins/inputs/kernel/{psi_linux.go => psi.go} | 2 ++ 1 file changed, 2 insertions(+) rename plugins/inputs/kernel/{psi_linux.go => psi.go} (99%) diff --git a/plugins/inputs/kernel/psi_linux.go b/plugins/inputs/kernel/psi.go similarity index 99% rename from plugins/inputs/kernel/psi_linux.go rename to plugins/inputs/kernel/psi.go index 4b33f1b404ffd..37a1dd562b62e 100644 --- a/plugins/inputs/kernel/psi_linux.go +++ b/plugins/inputs/kernel/psi.go @@ -1,3 +1,5 @@ +//go:build linux + package kernel import ( From 4537dffd896050f40f178f6e744afd2d4157cf06 Mon Sep 17 00:00:00 2001 From: iBug Date: Fri, 5 Jan 2024 01:21:21 +0800 Subject: [PATCH 20/26] Remove trailing punctuations in error messages --- plugins/inputs/kernel/kernel.go | 4 ++-- plugins/inputs/kernel/kernel_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index c4197b83f58aa..00a81361e6318 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -46,13 +46,13 @@ func (k *Kernel) Init() error { if k.optCollect["ksm"] { if _, err := os.Stat(k.ksmStatsDir); os.IsNotExist(err) { // ksm probably not enabled in the kernel, bail out early - return fmt.Errorf("directory %q does not exist. Is KSM enabled in this kernel?", k.ksmStatsDir) + return fmt.Errorf("directory %q does not exist. KSM is not enabled in this kernel", k.ksmStatsDir) } } if k.optCollect["psi"] { if _, err := os.Stat(k.psiDir); os.IsNotExist(err) { // psi probably not supported in the kernel, bail out early - return fmt.Errorf("directory %q does not exist. Is PSI enabled in this kernel?", k.psiDir) + return fmt.Errorf("directory %q does not exist. PSI is not enabled in this kernel", k.psiDir) } } return nil diff --git a/plugins/inputs/kernel/kernel_test.go b/plugins/inputs/kernel/kernel_test.go index d249e63c8f70b..26fa7dcbe549a 100644 --- a/plugins/inputs/kernel/kernel_test.go +++ b/plugins/inputs/kernel/kernel_test.go @@ -200,7 +200,7 @@ func TestKSMEnabledWrongDir(t *testing.T) { ConfigCollect: []string{"ksm"}, } - require.ErrorContains(t, k.Init(), "Is KSM enabled in this kernel?") + require.ErrorContains(t, k.Init(), "KSM is not enabled in this kernel") } func TestKSMDisabledNoKSMTags(t *testing.T) { From 1ea12c2cf4f2151b3bf301fd6dd4b3764d7139ee Mon Sep 17 00:00:00 2001 From: iBug Date: Fri, 5 Jan 2024 03:45:45 +0800 Subject: [PATCH 21/26] Add TestPSIEnabledWrongDir --- plugins/inputs/kernel/psi_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/inputs/kernel/psi_test.go b/plugins/inputs/kernel/psi_test.go index 44cffc6ee9f54..7aca6b3c0bf42 100644 --- a/plugins/inputs/kernel/psi_test.go +++ b/plugins/inputs/kernel/psi_test.go @@ -10,6 +10,15 @@ import ( "github.com/stretchr/testify/require" ) +func TestPSIEnabledWrongDir(t *testing.T) { + k := Kernel{ + psiDir: "testdata/this_file_does_not_exist", + ConfigCollect: []string{"psi"}, + } + + require.ErrorContains(t, k.Init(), "PSI is not enabled in this kernel") +} + func TestPSIStats(t *testing.T) { var ( k *Kernel From 588f12e28dc277a8de008c9a207c36407c08939e Mon Sep 17 00:00:00 2001 From: iBug Date: Fri, 5 Jan 2024 05:36:26 +0800 Subject: [PATCH 22/26] inputs.kernel: Use k.psiDir for initializing procfs.FS, add test data --- plugins/inputs/kernel/kernel.go | 8 +++- plugins/inputs/kernel/psi.go | 10 +---- plugins/inputs/kernel/psi_test.go | 41 ++++--------------- plugins/inputs/kernel/testdata/pressure/cpu | 2 + plugins/inputs/kernel/testdata/pressure/io | 2 + .../inputs/kernel/testdata/pressure/memory | 2 + 6 files changed, 22 insertions(+), 43 deletions(-) create mode 100644 plugins/inputs/kernel/testdata/pressure/cpu create mode 100644 plugins/inputs/kernel/testdata/pressure/io create mode 100644 plugins/inputs/kernel/testdata/pressure/memory diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index 00a81361e6318..b84a54aa7e2cc 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -13,6 +13,7 @@ import ( "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/inputs" + "github.com/prometheus/procfs" ) //go:embed sample.conf @@ -35,6 +36,7 @@ type Kernel struct { entropyStatFile string ksmStatsDir string psiDir string + procfs procfs.FS } func (k *Kernel) Init() error { @@ -50,9 +52,11 @@ func (k *Kernel) Init() error { } } if k.optCollect["psi"] { - if _, err := os.Stat(k.psiDir); os.IsNotExist(err) { + procdir := filepath.Dir(k.psiDir) + var err error + if k.procfs, err = procfs.NewFS(procdir); err != nil { // psi probably not supported in the kernel, bail out early - return fmt.Errorf("directory %q does not exist. PSI is not enabled in this kernel", k.psiDir) + return fmt.Errorf("failed to initialize procfs on %s: %w", procdir, err) } } return nil diff --git a/plugins/inputs/kernel/psi.go b/plugins/inputs/kernel/psi.go index 37a1dd562b62e..b8b49cdf6fea9 100644 --- a/plugins/inputs/kernel/psi.go +++ b/plugins/inputs/kernel/psi.go @@ -21,16 +21,10 @@ func (k *Kernel) gatherPressure(acc telegraf.Accumulator) error { } // getPressureValues - Get the pressure values from /proc/pressure/* -func (*Kernel) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { - var fs procfs.FS - fs, err = procfs.NewDefaultFS() - if err != nil { - return nil, fmt.Errorf("procfs not available: %w", err) - } - +func (k *Kernel) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { pressures = make(map[string]procfs.PSIStats) for _, resource := range []string{"cpu", "memory", "io"} { - pressures[resource], err = fs.PSIStatsForResource(resource) + pressures[resource], err = k.procfs.PSIStatsForResource(resource) if err != nil { return nil, fmt.Errorf("failed to read %s pressure: %w", resource, err) } diff --git a/plugins/inputs/kernel/psi_test.go b/plugins/inputs/kernel/psi_test.go index 7aca6b3c0bf42..10f2025e5b2ae 100644 --- a/plugins/inputs/kernel/psi_test.go +++ b/plugins/inputs/kernel/psi_test.go @@ -6,50 +6,27 @@ import ( "testing" "github.com/influxdata/telegraf/testutil" - "github.com/prometheus/procfs" "github.com/stretchr/testify/require" ) func TestPSIEnabledWrongDir(t *testing.T) { k := Kernel{ - psiDir: "testdata/this_file_does_not_exist", + psiDir: "testdata/this_directory_does_not_exist/stub", ConfigCollect: []string{"psi"}, } - require.ErrorContains(t, k.Init(), "PSI is not enabled in this kernel") + require.ErrorContains(t, k.Init(), "failed to initialize procfs on ") } func TestPSIStats(t *testing.T) { - var ( - k *Kernel - err error - acc testutil.Accumulator - ) + var acc testutil.Accumulator - mockPressureSome := &procfs.PSILine{ - Avg10: 10, - Avg60: 60, - Avg300: 300, - Total: 114514, - } - mockPressureFull := &procfs.PSILine{ - Avg10: 1, - Avg60: 6, - Avg300: 30, - Total: 11451, - } - mockPSIStats := procfs.PSIStats{ - Some: mockPressureSome, - Full: mockPressureFull, - } - mockStats := map[string]procfs.PSIStats{ - "cpu": mockPSIStats, - "memory": mockPSIStats, - "io": mockPSIStats, + k := Kernel{ + psiDir: "testdata/pressure", + ConfigCollect: []string{"psi"}, } - - err = k.gatherPressure(&acc) - require.NoError(t, err) + require.NoError(t, k.Init()) + require.NoError(t, k.gatherPressure(&acc)) // separate fields for gauges and counters pressureFields := map[string]map[string]interface{}{ @@ -73,8 +50,6 @@ func TestPSIStats(t *testing.T) { }, } - acc.ClearMetrics() - k.uploadPressure(mockStats, &acc) for _, typ := range []string{"some", "full"} { for _, resource := range []string{"cpu", "memory", "io"} { if resource == "cpu" && typ == "full" { diff --git a/plugins/inputs/kernel/testdata/pressure/cpu b/plugins/inputs/kernel/testdata/pressure/cpu new file mode 100644 index 0000000000000..1093304726260 --- /dev/null +++ b/plugins/inputs/kernel/testdata/pressure/cpu @@ -0,0 +1,2 @@ +some avg10=10.00 avg60=60.00 avg300=300.00 total=114514 +full avg10=0.00 avg60=0.00 avg300=0.00 total=0 diff --git a/plugins/inputs/kernel/testdata/pressure/io b/plugins/inputs/kernel/testdata/pressure/io new file mode 100644 index 0000000000000..613432c83cacb --- /dev/null +++ b/plugins/inputs/kernel/testdata/pressure/io @@ -0,0 +1,2 @@ +some avg10=10.00 avg60=60.00 avg300=300.00 total=114514 +full avg10=1.00 avg60=6.00 avg300=30.00 total=11451 diff --git a/plugins/inputs/kernel/testdata/pressure/memory b/plugins/inputs/kernel/testdata/pressure/memory new file mode 100644 index 0000000000000..613432c83cacb --- /dev/null +++ b/plugins/inputs/kernel/testdata/pressure/memory @@ -0,0 +1,2 @@ +some avg10=10.00 avg60=60.00 avg300=300.00 total=114514 +full avg10=1.00 avg60=6.00 avg300=30.00 total=11451 From 2067d63648190858ba93c1fec3825fe8c77bc214 Mon Sep 17 00:00:00 2001 From: iBug Date: Fri, 5 Jan 2024 05:40:42 +0800 Subject: [PATCH 23/26] inputs.kernel: Merge getPressureValues and uploadPressure --- plugins/inputs/kernel/psi.go | 44 +++++++++++------------------------- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/plugins/inputs/kernel/psi.go b/plugins/inputs/kernel/psi.go index b8b49cdf6fea9..28d54ac3b62a0 100644 --- a/plugins/inputs/kernel/psi.go +++ b/plugins/inputs/kernel/psi.go @@ -10,34 +10,23 @@ import ( "github.com/prometheus/procfs" ) -// Gather Psi metrics +// Gather PSI metrics func (k *Kernel) gatherPressure(acc telegraf.Accumulator) error { - pressures, err := k.getPressureValues() - if err != nil { - return err - } - k.uploadPressure(pressures, acc) - return nil -} - -// getPressureValues - Get the pressure values from /proc/pressure/* -func (k *Kernel) getPressureValues() (pressures map[string]procfs.PSIStats, err error) { - pressures = make(map[string]procfs.PSIStats) for _, resource := range []string{"cpu", "memory", "io"} { - pressures[resource], err = k.procfs.PSIStatsForResource(resource) + now := time.Now() + psiStats, err := k.procfs.PSIStatsForResource(resource) if err != nil { - return nil, fmt.Errorf("failed to read %s pressure: %w", resource, err) + return fmt.Errorf("failed to read %s pressure: %w", resource, err) } - } - return pressures, nil -} -// uploadPressure Uploads all pressure value to corrosponding fields -// NOTE: resource=cpu,type=full is omitted because it is always zero -func (*Kernel) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf.Accumulator) { - for _, typ := range []string{"some", "full"} { - for _, resource := range []string{"cpu", "memory", "io"} { + stats := map[string]*procfs.PSILine{ + "some": psiStats.Some, + "full": psiStats.Full, + } + + for _, typ := range []string{"some", "full"} { if resource == "cpu" && typ == "full" { + // resource=cpu,type=full is omitted because it is always zero continue } @@ -45,16 +34,8 @@ func (*Kernel) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf "resource": resource, "type": typ, } + stat := stats[typ] - var stat *procfs.PSILine - switch typ { - case "some": - stat = pressures[resource].Some - case "full": - stat = pressures[resource].Full - } - - now := time.Now() acc.AddCounter("pressure", map[string]interface{}{ "total": stat.Total, }, tags, now) @@ -65,4 +46,5 @@ func (*Kernel) uploadPressure(pressures map[string]procfs.PSIStats, acc telegraf }, tags, now) } } + return nil } From 9261d75aecd8972ae524d0598a979649f19aff4e Mon Sep 17 00:00:00 2001 From: iBug Date: Fri, 5 Jan 2024 18:15:38 +0800 Subject: [PATCH 24/26] Apply suggestions from code review Co-authored-by: Sven Rebhan <36194019+srebhan@users.noreply.github.com> --- plugins/inputs/kernel/kernel.go | 5 +- plugins/inputs/kernel/psi_test.go | 182 ++++++++++++++++++++++-------- 2 files changed, 139 insertions(+), 48 deletions(-) diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index b84a54aa7e2cc..b63f7e2fa6592 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -11,9 +11,10 @@ import ( "path/filepath" "strconv" + "github.com/prometheus/procfs" + "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/inputs" - "github.com/prometheus/procfs" ) //go:embed sample.conf @@ -158,7 +159,7 @@ func (k *Kernel) Gather(acc telegraf.Accumulator) error { if k.optCollect["psi"] { if err := k.gatherPressure(acc); err != nil { - return err + return fmt.Errorf("gathering pressure failed: %w", err) } } diff --git a/plugins/inputs/kernel/psi_test.go b/plugins/inputs/kernel/psi_test.go index 10f2025e5b2ae..0228b20b3accc 100644 --- a/plugins/inputs/kernel/psi_test.go +++ b/plugins/inputs/kernel/psi_test.go @@ -19,58 +19,148 @@ func TestPSIEnabledWrongDir(t *testing.T) { } func TestPSIStats(t *testing.T) { - var acc testutil.Accumulator - k := Kernel{ psiDir: "testdata/pressure", ConfigCollect: []string{"psi"}, } require.NoError(t, k.Init()) - require.NoError(t, k.gatherPressure(&acc)) - - // separate fields for gauges and counters - pressureFields := map[string]map[string]interface{}{ - "some": { - "avg10": float64(10), - "avg60": float64(60), - "avg300": float64(300), - }, - "full": { - "avg10": float64(1), - "avg60": float64(6), - "avg300": float64(30), - }, - } - pressureTotalFields := map[string]map[string]interface{}{ - "some": { - "total": uint64(114514), - }, - "full": { - "total": uint64(11451), - }, - } - for _, typ := range []string{"some", "full"} { - for _, resource := range []string{"cpu", "memory", "io"} { - if resource == "cpu" && typ == "full" { - continue - } - - tags := map[string]string{ - "resource": resource, - "type": typ, - } - - acc.AssertContainsTaggedFields(t, "pressure", pressureFields[typ], tags) - acc.AssertContainsTaggedFields(t, "pressure", pressureTotalFields[typ], tags) - } - } + var acc testutil.Accumulator + require.NoError(t, k.gatherPressure(&acc)) - // The combination "resource=cpu,type=full" should NOT appear anywhere - forbiddenTags := map[string]string{ - "resource": "cpu", - "type": "full", + expected := []telegraf.Metric{ + metric.New( + "pressure", + map[string]string{ + "resource": "cpu", + "type": "some", + }, + map[string]interface{}{ + "avg10": float64(10), + "avg60": float64(60), + "avg300": float64(300), + }, + time.Unix(0,0), + telegraf.Gauge, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "cpu", + "type": "some", + }, + map[string]interface{}{ + "total": uint64(114514), + }, + time.Unix(0,0), + telegraf.Counter, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "memory", + "type": "some", + }, + map[string]interface{}{ + "avg10": float64(10), + "avg60": float64(60), + "avg300": float64(300), + }, + time.Unix(0,0), + telegraf.Gauge, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "memory", + "type": "some", + }, + map[string]interface{}{ + "total": uint64(114514), + }, + time.Unix(0,0), + telegraf.Counter, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "io", + "type": "some", + }, + map[string]interface{}{ + "avg10": float64(10), + "avg60": float64(60), + "avg300": float64(300), + }, + time.Unix(0,0), + telegraf.Gauge, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "io", + "type": "some", + }, + map[string]interface{}{ + "total": uint64(114514), + }, + time.Unix(0,0), + telegraf.Counter, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "memory", + "type": "full", + }, + map[string]interface{}{ + "avg10": float64(1), + "avg60": float64(6), + "avg300": float64(30), + }, + time.Unix(0,0), + telegraf.Gauge, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "memory", + "type": "full", + }, + map[string]interface{}{ + "total": uint64(11451), + }, + time.Unix(0,0), + telegraf.Counter, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "io", + "type": "full", + }, + map[string]interface{}{ + "avg10": float64(1), + "avg60": float64(6), + "avg300": float64(30), + }, + time.Unix(0,0), + telegraf.Gauge, + ), + metric.New( + "pressure", + map[string]string{ + "resource": "io", + "type": "full", + }, + map[string]interface{}{ + "total": uint64(11451), + }, + time.Unix(0,0), + telegraf.Counter, + ), } - acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureFields["full"], forbiddenTags) - acc.AssertDoesNotContainsTaggedFields(t, "pressure", pressureTotalFields["full"], forbiddenTags) + + actual := acc.GetTelegrafMetrics() + testutil.RequireMeticsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics()) } From 56dd9b2f498c2a10cddc39680b48b5faa1d78d3b Mon Sep 17 00:00:00 2001 From: iBug Date: Fri, 5 Jan 2024 18:55:13 +0800 Subject: [PATCH 25/26] Format with goimports -local --- plugins/inputs/kernel/kernel.go | 2 +- plugins/inputs/kernel/psi.go | 3 ++- plugins/inputs/kernel/psi_test.go | 30 +++++++++++++++++------------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index b63f7e2fa6592..7e79c4936487e 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -12,7 +12,7 @@ import ( "strconv" "github.com/prometheus/procfs" - + "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/inputs" ) diff --git a/plugins/inputs/kernel/psi.go b/plugins/inputs/kernel/psi.go index 28d54ac3b62a0..c85e2cafec472 100644 --- a/plugins/inputs/kernel/psi.go +++ b/plugins/inputs/kernel/psi.go @@ -6,8 +6,9 @@ import ( "fmt" "time" - "github.com/influxdata/telegraf" "github.com/prometheus/procfs" + + "github.com/influxdata/telegraf" ) // Gather PSI metrics diff --git a/plugins/inputs/kernel/psi_test.go b/plugins/inputs/kernel/psi_test.go index 0228b20b3accc..6552dfe98d587 100644 --- a/plugins/inputs/kernel/psi_test.go +++ b/plugins/inputs/kernel/psi_test.go @@ -4,9 +4,13 @@ package kernel import ( "testing" + "time" - "github.com/influxdata/telegraf/testutil" "github.com/stretchr/testify/require" + + "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/metric" + "github.com/influxdata/telegraf/testutil" ) func TestPSIEnabledWrongDir(t *testing.T) { @@ -40,7 +44,7 @@ func TestPSIStats(t *testing.T) { "avg60": float64(60), "avg300": float64(300), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Gauge, ), metric.New( @@ -52,7 +56,7 @@ func TestPSIStats(t *testing.T) { map[string]interface{}{ "total": uint64(114514), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Counter, ), metric.New( @@ -66,7 +70,7 @@ func TestPSIStats(t *testing.T) { "avg60": float64(60), "avg300": float64(300), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Gauge, ), metric.New( @@ -78,7 +82,7 @@ func TestPSIStats(t *testing.T) { map[string]interface{}{ "total": uint64(114514), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Counter, ), metric.New( @@ -92,7 +96,7 @@ func TestPSIStats(t *testing.T) { "avg60": float64(60), "avg300": float64(300), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Gauge, ), metric.New( @@ -104,7 +108,7 @@ func TestPSIStats(t *testing.T) { map[string]interface{}{ "total": uint64(114514), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Counter, ), metric.New( @@ -118,7 +122,7 @@ func TestPSIStats(t *testing.T) { "avg60": float64(6), "avg300": float64(30), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Gauge, ), metric.New( @@ -130,7 +134,7 @@ func TestPSIStats(t *testing.T) { map[string]interface{}{ "total": uint64(11451), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Counter, ), metric.New( @@ -144,7 +148,7 @@ func TestPSIStats(t *testing.T) { "avg60": float64(6), "avg300": float64(30), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Gauge, ), metric.New( @@ -156,11 +160,11 @@ func TestPSIStats(t *testing.T) { map[string]interface{}{ "total": uint64(11451), }, - time.Unix(0,0), + time.Unix(0, 0), telegraf.Counter, ), } - + actual := acc.GetTelegrafMetrics() - testutil.RequireMeticsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics()) + testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics()) } From 4c12350acf5dd25c9ebaf44d1b56e327422a94e0 Mon Sep 17 00:00:00 2001 From: iBug Date: Fri, 5 Jan 2024 19:27:03 +0800 Subject: [PATCH 26/26] inputs/kernel/kernel.go: Revert error wrapping on k.gatherPressure --- plugins/inputs/kernel/kernel.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/inputs/kernel/kernel.go b/plugins/inputs/kernel/kernel.go index 7e79c4936487e..58e3af0448704 100644 --- a/plugins/inputs/kernel/kernel.go +++ b/plugins/inputs/kernel/kernel.go @@ -159,7 +159,7 @@ func (k *Kernel) Gather(acc telegraf.Accumulator) error { if k.optCollect["psi"] { if err := k.gatherPressure(acc); err != nil { - return fmt.Errorf("gathering pressure failed: %w", err) + return err } }