Add device name as a tag in disk stats (#1807)

* return partition stat alongside disk stat from disk usage method, and report device name (minus /dev/) as a tag in disk stats

* update system/disk tests to include new partition stat return value from disk usage method calls

* update changelog for #1807 (use device name instead of path to report disk stats)
This commit is contained in:
Nathan D Acuff 2016-12-05 12:42:36 -05:00 committed by Cameron Sparr
parent 1d1afe6481
commit d518d7d806
5 changed files with 46 additions and 13 deletions

View File

@ -9,6 +9,7 @@
- [#1997](https://github.com/influxdata/telegraf/issues/1997): Non-default HTTP timeouts for RabbitMQ plugin. - [#1997](https://github.com/influxdata/telegraf/issues/1997): Non-default HTTP timeouts for RabbitMQ plugin.
- [#2074](https://github.com/influxdata/telegraf/pull/2074): "discard" output plugin added, primarily for testing purposes. - [#2074](https://github.com/influxdata/telegraf/pull/2074): "discard" output plugin added, primarily for testing purposes.
- [#1965](https://github.com/influxdata/telegraf/pull/1965): The JSON parser can now parse an array of objects using the same configuration. - [#1965](https://github.com/influxdata/telegraf/pull/1965): The JSON parser can now parse an array of objects using the same configuration.
- [#1807](https://github.com/influxdata/telegraf/pull/1807): Option to use device name rather than path for reporting disk stats.
### Bugfixes ### Bugfixes

View File

@ -2,6 +2,7 @@ package system
import ( import (
"fmt" "fmt"
"strings"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/inputs"
@ -41,18 +42,19 @@ func (s *DiskStats) Gather(acc telegraf.Accumulator) error {
s.MountPoints = s.Mountpoints s.MountPoints = s.Mountpoints
} }
disks, err := s.ps.DiskUsage(s.MountPoints, s.IgnoreFS) disks, partitions, 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 i, du := range disks {
if du.Total == 0 { if du.Total == 0 {
// Skip dummy filesystem (procfs, cgroupfs, ...) // Skip dummy filesystem (procfs, cgroupfs, ...)
continue continue
} }
tags := map[string]string{ tags := map[string]string{
"path": du.Path, "path": du.Path,
"device": strings.Replace(partitions[i].Device, "/dev/", "", -1),
"fstype": du.Fstype, "fstype": du.Fstype,
} }
var used_percent float64 var used_percent float64

View File

@ -50,9 +50,33 @@ func TestDiskStats(t *testing.T) {
}, },
} }
mps.On("DiskUsage", []string(nil), []string(nil)).Return(duAll, nil) psAll := []*disk.PartitionStat{
mps.On("DiskUsage", []string{"/", "/dev"}, []string(nil)).Return(duFiltered, nil) {
mps.On("DiskUsage", []string{"/", "/home"}, []string(nil)).Return(duAll, nil) Device: "/dev/sda",
Mountpoint: "/",
Fstype: "ext4",
Opts: "",
},
{
Device: "/dev/sdb",
Mountpoint: "/home",
Fstype: "ext4",
Opts: "",
},
}
psFiltered := []*disk.PartitionStat{
{
Device: "/dev/sda",
Mountpoint: "/",
Fstype: "ext4",
Opts: "",
},
}
mps.On("DiskUsage", []string(nil), []string(nil)).Return(duAll, psAll, nil)
mps.On("DiskUsage", []string{"/", "/dev"}, []string(nil)).Return(duFiltered, psFiltered, nil)
mps.On("DiskUsage", []string{"/", "/home"}, []string(nil)).Return(duAll, psAll, nil)
err = (&DiskStats{ps: &mps}).Gather(&acc) err = (&DiskStats{ps: &mps}).Gather(&acc)
require.NoError(t, err) require.NoError(t, err)
@ -64,10 +88,12 @@ func TestDiskStats(t *testing.T) {
tags1 := map[string]string{ tags1 := map[string]string{
"path": "/", "path": "/",
"fstype": "ext4", "fstype": "ext4",
"device": "sda",
} }
tags2 := map[string]string{ tags2 := map[string]string{
"path": "/home", "path": "/home",
"fstype": "ext4", "fstype": "ext4",
"device": "sdb",
} }
fields1 := map[string]interface{}{ fields1 := map[string]interface{}{

View File

@ -33,13 +33,14 @@ func (m *MockPS) CPUTimes(perCPU, totalCPU bool) ([]cpu.TimesStat, error) {
return r0, r1 return r0, r1
} }
func (m *MockPS) DiskUsage(mountPointFilter []string, fstypeExclude []string) ([]*disk.UsageStat, error) { func (m *MockPS) DiskUsage(mountPointFilter []string, fstypeExclude []string) ([]*disk.UsageStat, []*disk.PartitionStat, error) {
ret := m.Called(mountPointFilter, fstypeExclude) ret := m.Called(mountPointFilter, fstypeExclude)
r0 := ret.Get(0).([]*disk.UsageStat) r0 := ret.Get(0).([]*disk.UsageStat)
r1 := ret.Error(1) r1 := ret.Get(1).([]*disk.PartitionStat)
r2 := ret.Error(2)
return r0, r1 return r0, r1, r2
} }
func (m *MockPS) NetIO() ([]net.IOCountersStat, error) { func (m *MockPS) NetIO() ([]net.IOCountersStat, error) {

View File

@ -14,7 +14,7 @@ import (
type PS interface { type PS interface {
CPUTimes(perCPU, totalCPU bool) ([]cpu.TimesStat, error) CPUTimes(perCPU, totalCPU bool) ([]cpu.TimesStat, error)
DiskUsage(mountPointFilter []string, fstypeExclude []string) ([]*disk.UsageStat, error) DiskUsage(mountPointFilter []string, fstypeExclude []string) ([]*disk.UsageStat, []*disk.PartitionStat, error)
NetIO() ([]net.IOCountersStat, error) NetIO() ([]net.IOCountersStat, error)
NetProto() ([]net.ProtoCountersStat, error) NetProto() ([]net.ProtoCountersStat, error)
DiskIO() (map[string]disk.IOCountersStat, error) DiskIO() (map[string]disk.IOCountersStat, error)
@ -54,10 +54,10 @@ func (s *systemPS) CPUTimes(perCPU, totalCPU bool) ([]cpu.TimesStat, error) {
func (s *systemPS) DiskUsage( func (s *systemPS) DiskUsage(
mountPointFilter []string, mountPointFilter []string,
fstypeExclude []string, fstypeExclude []string,
) ([]*disk.UsageStat, error) { ) ([]*disk.UsageStat, []*disk.PartitionStat, error) {
parts, err := disk.Partitions(true) parts, err := disk.Partitions(true)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// Make a "set" out of the filter slice // Make a "set" out of the filter slice
@ -71,6 +71,7 @@ func (s *systemPS) DiskUsage(
} }
var usage []*disk.UsageStat var usage []*disk.UsageStat
var partitions []*disk.PartitionStat
for _, p := range parts { for _, p := range parts {
if len(mountPointFilter) > 0 { if len(mountPointFilter) > 0 {
@ -85,9 +86,10 @@ func (s *systemPS) DiskUsage(
if _, err := os.Stat(mountpoint); err == nil { if _, err := os.Stat(mountpoint); err == nil {
du, err := disk.Usage(mountpoint) du, err := disk.Usage(mountpoint)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
du.Path = p.Mountpoint du.Path = p.Mountpoint
// If the mount point is a member of the exclude set, // If the mount point is a member of the exclude set,
// don't gather info on it. // don't gather info on it.
_, ok := fstypeExcludeSet[p.Fstype] _, ok := fstypeExcludeSet[p.Fstype]
@ -96,10 +98,11 @@ func (s *systemPS) DiskUsage(
} }
du.Fstype = p.Fstype du.Fstype = p.Fstype
usage = append(usage, du) usage = append(usage, du)
partitions = append(partitions, &p)
} }
} }
return usage, nil return usage, partitions, nil
} }
func (s *systemPS) NetProto() ([]net.ProtoCountersStat, error) { func (s *systemPS) NetProto() ([]net.ProtoCountersStat, error) {