feat(inputs.procstat): Report consistent I/O on Linux (#15186)
This commit is contained in:
parent
bfda888453
commit
46dbab0c0d
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -1,6 +1,16 @@
|
||||||
<!-- markdownlint-disable MD024 -->
|
<!-- markdownlint-disable MD024 -->
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Important Changes
|
||||||
|
|
||||||
|
- [PR #15186](https://github.com/influxdata/telegraf/pull/15186) changes the
|
||||||
|
meaning of `inputs.procstat` fields `read_bytes` and `write_bytes` on Linux
|
||||||
|
to now contain _all_ I/O operations for consistency with other
|
||||||
|
operating-systems. The previous values are output as `disk_read_bytes` and
|
||||||
|
`disk_write_bytes` measuring _only_ the I/O on the storage layer.
|
||||||
|
|
||||||
## v1.30.2 [2024-04-22]
|
## v1.30.2 [2024-04-22]
|
||||||
|
|
||||||
### Important Changes
|
### Important Changes
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,8 @@ Below are an example set of tags and fields:
|
||||||
- cpu_time_system (float)
|
- cpu_time_system (float)
|
||||||
- cpu_time_user (float)
|
- cpu_time_user (float)
|
||||||
- cpu_usage (float)
|
- cpu_usage (float)
|
||||||
|
- disk_read_bytes (int, Linux only, *telegraf* may need to be ran as **root**)
|
||||||
|
- disk_write_bytes (int, Linux only, *telegraf* may need to be ran as **root**)
|
||||||
- involuntary_context_switches (int)
|
- involuntary_context_switches (int)
|
||||||
- major_faults (int)
|
- major_faults (int)
|
||||||
- memory_anonymous (int)
|
- memory_anonymous (int)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs"
|
||||||
|
|
||||||
"github.com/coreos/go-systemd/v22/dbus"
|
"github.com/coreos/go-systemd/v22/dbus"
|
||||||
"github.com/shirou/gopsutil/v3/process"
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
|
|
@ -76,3 +79,27 @@ func findBySystemdUnits(units []string) ([]processGroup, error) {
|
||||||
func findByWindowsServices(_ []string) ([]processGroup, error) {
|
func findByWindowsServices(_ []string) ([]processGroup, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func collectTotalReadWrite(proc Process) (r, w uint64, err error) {
|
||||||
|
path := procfs.DefaultMountPoint
|
||||||
|
if hp := os.Getenv("HOST_PROC"); hp != "" {
|
||||||
|
path = hp
|
||||||
|
}
|
||||||
|
|
||||||
|
fs, err := procfs.NewFS(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := fs.Proc(int(proc.PID()))
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := p.IO()
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return stat.RChar, stat.WChar, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,3 +25,7 @@ func findBySystemdUnits(_ []string) ([]processGroup, error) {
|
||||||
func findByWindowsServices(_ []string) ([]processGroup, error) {
|
func findByWindowsServices(_ []string) ([]processGroup, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func collectTotalReadWrite(_ Process) (r, w uint64, err error) {
|
||||||
|
return 0, 0, errors.ErrUnsupported
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,3 +82,7 @@ func findByWindowsServices(services []string) ([]processGroup, error) {
|
||||||
|
|
||||||
return groups, nil
|
return groups, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func collectTotalReadWrite(_ Process) (r, w uint64, err error) {
|
||||||
|
return 0, 0, errors.ErrUnsupported
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,15 @@ func (p *Proc) Metric(prefix string, tagging map[string]bool, solarisMode bool)
|
||||||
fields[prefix+"write_bytes"] = io.WriteBytes
|
fields[prefix+"write_bytes"] = io.WriteBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Linux fixup for gopsutils exposing the disk-only-IO instead of the total
|
||||||
|
// I/O as for example on Windows
|
||||||
|
if rc, wc, err := collectTotalReadWrite(p); err == nil {
|
||||||
|
fields[prefix+"read_bytes"] = rc
|
||||||
|
fields[prefix+"write_bytes"] = wc
|
||||||
|
fields[prefix+"disk_read_bytes"] = io.ReadBytes
|
||||||
|
fields[prefix+"disk_write_bytes"] = io.WriteBytes
|
||||||
|
}
|
||||||
|
|
||||||
createdAt, err := p.CreateTime() // returns epoch in ms
|
createdAt, err := p.CreateTime() // returns epoch in ms
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fields[prefix+"created_at"] = createdAt * 1000000 // ms to ns
|
fields[prefix+"created_at"] = createdAt * 1000000 // ms to ns
|
||||||
|
|
|
||||||
|
|
@ -347,8 +347,6 @@ func TestGather_ProcessName(t *testing.T) {
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
require.NoError(t, p.Gather(&acc))
|
require.NoError(t, p.Gather(&acc))
|
||||||
|
|
||||||
testutil.PrintMetrics(acc.GetTelegrafMetrics())
|
|
||||||
require.Equal(t, "custom_name", acc.TagValue("procstat", "process_name"))
|
require.Equal(t, "custom_name", acc.TagValue("procstat", "process_name"))
|
||||||
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime())
|
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue