Ignore boring filesystems from disk plugin

Modern Linux has a lots of boring filesystem (tmpfs on /dev, devpts on
/dev/pts, lots of cgroup on /sys/fs/cgroup/*, ...).

* Ignore filesystem with 0 bytes (this cover cgroup, devpts and other).
* Add IgnoreFS to ignore additional FS by their type. Add tmpfs and
  devtmpfs as default ignored type.
This commit is contained in:
Pierre Fersing 2016-02-22 18:29:10 +01:00 committed by Cameron Sparr
parent 9687f71a17
commit 47ad73cc89
5 changed files with 34 additions and 10 deletions

View File

@ -97,6 +97,10 @@
# Setting mountpoints will restrict the stats to the specified mountpoints. # Setting mountpoints will restrict the stats to the specified mountpoints.
# mount_points=["/"] # mount_points=["/"]
# Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually
# present on /run, /var/run, /dev/shm or /dev).
ignore_fs = ["tmpfs", "devtmpfs"]
# Read metrics about disk IO by device # Read metrics about disk IO by device
[[inputs.diskio]] [[inputs.diskio]]
# By default, telegraf will gather stats for all devices including # By default, telegraf will gather stats for all devices including

View File

@ -14,6 +14,7 @@ type DiskStats struct {
Mountpoints []string Mountpoints []string
MountPoints []string MountPoints []string
IgnoreFS []string `toml:"ignore_fs"`
} }
func (_ *DiskStats) Description() string { func (_ *DiskStats) Description() string {
@ -24,6 +25,10 @@ var diskSampleConfig = `
## By default, telegraf gather stats for all mountpoints. ## By default, telegraf gather stats for all mountpoints.
## Setting mountpoints will restrict the stats to the specified mountpoints. ## Setting mountpoints will restrict the stats to the specified mountpoints.
# mount_points = ["/"] # mount_points = ["/"]
# Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually
# present on /run, /var/run, /dev/shm or /dev).
ignore_fs = ["tmpfs", "devtmpfs"]
` `
func (_ *DiskStats) SampleConfig() string { func (_ *DiskStats) SampleConfig() string {
@ -36,12 +41,16 @@ func (s *DiskStats) Gather(acc telegraf.Accumulator) error {
s.MountPoints = s.Mountpoints s.MountPoints = s.Mountpoints
} }
disks, err := s.ps.DiskUsage(s.MountPoints) disks, err := s.ps.DiskUsage(s.MountPoints, s.IgnoreFS)
if err != nil { if err != nil {
return fmt.Errorf("error getting disk usage info: %s", err) return fmt.Errorf("error getting disk usage info: %s", err)
} }
for _, du := range disks { for _, du := range disks {
if du.Total == 0 {
// Skip dummy filesystem (procfs, cgroupfs, ...)
continue
}
tags := map[string]string{ tags := map[string]string{
"path": du.Path, "path": du.Path,
"fstype": du.Fstype, "fstype": du.Fstype,

View File

@ -50,9 +50,9 @@ func TestDiskStats(t *testing.T) {
}, },
} }
mps.On("DiskUsage", []string(nil)).Return(duAll, nil) mps.On("DiskUsage", []string(nil), []string(nil)).Return(duAll, nil)
mps.On("DiskUsage", []string{"/", "/dev"}).Return(duFiltered, nil) mps.On("DiskUsage", []string{"/", "/dev"}, []string(nil)).Return(duFiltered, nil)
mps.On("DiskUsage", []string{"/", "/home"}).Return(duAll, nil) mps.On("DiskUsage", []string{"/", "/home"}, []string(nil)).Return(duAll, nil)
err = (&DiskStats{ps: &mps}).Gather(&acc) err = (&DiskStats{ps: &mps}).Gather(&acc)
require.NoError(t, err) require.NoError(t, err)

View File

@ -33,8 +33,8 @@ func (m *MockPS) CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error) {
return r0, r1 return r0, r1
} }
func (m *MockPS) DiskUsage(mountPointFilter []string) ([]*disk.DiskUsageStat, error) { func (m *MockPS) DiskUsage(mountPointFilter []string, fstypeExclude []string) ([]*disk.DiskUsageStat, error) {
ret := m.Called(mountPointFilter) ret := m.Called(mountPointFilter, fstypeExclude)
r0 := ret.Get(0).([]*disk.DiskUsageStat) r0 := ret.Get(0).([]*disk.DiskUsageStat)
r1 := ret.Error(1) r1 := ret.Error(1)

View File

@ -14,7 +14,7 @@ import (
type PS interface { type PS interface {
CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error) CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error)
DiskUsage(mountPointFilter []string) ([]*disk.DiskUsageStat, error) DiskUsage(mountPointFilter []string, fstypeExclude []string) ([]*disk.DiskUsageStat, error)
NetIO() ([]net.NetIOCountersStat, error) NetIO() ([]net.NetIOCountersStat, error)
NetProto() ([]net.NetProtoCountersStat, error) NetProto() ([]net.NetProtoCountersStat, error)
DiskIO() (map[string]disk.DiskIOCountersStat, error) DiskIO() (map[string]disk.DiskIOCountersStat, error)
@ -53,6 +53,7 @@ func (s *systemPS) CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error) {
func (s *systemPS) DiskUsage( func (s *systemPS) DiskUsage(
mountPointFilter []string, mountPointFilter []string,
fstypeExclude []string,
) ([]*disk.DiskUsageStat, error) { ) ([]*disk.DiskUsageStat, error) {
parts, err := disk.DiskPartitions(true) parts, err := disk.DiskPartitions(true)
if err != nil { if err != nil {
@ -60,9 +61,13 @@ func (s *systemPS) DiskUsage(
} }
// Make a "set" out of the filter slice // Make a "set" out of the filter slice
filterSet := make(map[string]bool) mountPointFilterSet := make(map[string]bool)
for _, filter := range mountPointFilter { for _, filter := range mountPointFilter {
filterSet[filter] = true mountPointFilterSet[filter] = true
}
fstypeExcludeSet := make(map[string]bool)
for _, filter := range fstypeExclude {
fstypeExcludeSet[filter] = true
} }
var usage []*disk.DiskUsageStat var usage []*disk.DiskUsageStat
@ -71,7 +76,7 @@ func (s *systemPS) DiskUsage(
if len(mountPointFilter) > 0 { if len(mountPointFilter) > 0 {
// If the mount point is not a member of the filter set, // If the mount point is not a member of the filter set,
// don't gather info on it. // don't gather info on it.
_, ok := filterSet[p.Mountpoint] _, ok := mountPointFilterSet[p.Mountpoint]
if !ok { if !ok {
continue continue
} }
@ -81,6 +86,12 @@ func (s *systemPS) DiskUsage(
if err != nil { if err != nil {
return nil, err return nil, err
} }
// If the mount point is a member of the exclude set,
// don't gather info on it.
_, ok := fstypeExcludeSet[p.Fstype]
if ok {
continue
}
du.Fstype = p.Fstype du.Fstype = p.Fstype
usage = append(usage, du) usage = append(usage, du)
} }