From b39b1958e85b26b93c5174485b414d6acd01275d Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Mon, 6 Apr 2015 14:53:43 -0700 Subject: [PATCH] Add VM and Swap stats --- plugins/system/mock_PS.go | 17 +++++++++++ plugins/system/system.go | 48 ++++++++++++++++++++++++++++++ plugins/system/system_test.go | 56 +++++++++++++++++++++++++++++++++++ testutil/accumulator.go | 31 +++++++++++++++---- 4 files changed, 146 insertions(+), 6 deletions(-) diff --git a/plugins/system/mock_PS.go b/plugins/system/mock_PS.go index e62407046..e3d142347 100644 --- a/plugins/system/mock_PS.go +++ b/plugins/system/mock_PS.go @@ -5,6 +5,7 @@ import "github.com/stretchr/testify/mock" import "github.com/influxdb/tivan/plugins/system/ps/cpu" import "github.com/influxdb/tivan/plugins/system/ps/disk" import "github.com/influxdb/tivan/plugins/system/ps/load" +import "github.com/influxdb/tivan/plugins/system/ps/mem" import "github.com/influxdb/tivan/plugins/system/ps/net" type MockPS struct { @@ -51,3 +52,19 @@ func (m *MockPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) { return r0, r1 } +func (m *MockPS) VMStat() (*mem.VirtualMemoryStat, error) { + ret := m.Called() + + r0 := ret.Get(0).(*mem.VirtualMemoryStat) + r1 := ret.Error(1) + + return r0, r1 +} +func (m *MockPS) SwapStat() (*mem.SwapMemoryStat, error) { + ret := m.Called() + + r0 := ret.Get(0).(*mem.SwapMemoryStat) + r1 := ret.Error(1) + + return r0, r1 +} diff --git a/plugins/system/system.go b/plugins/system/system.go index 5322f9167..94dbef8af 100644 --- a/plugins/system/system.go +++ b/plugins/system/system.go @@ -8,6 +8,7 @@ import ( "github.com/influxdb/tivan/plugins/system/ps/cpu" "github.com/influxdb/tivan/plugins/system/ps/disk" "github.com/influxdb/tivan/plugins/system/ps/load" + "github.com/influxdb/tivan/plugins/system/ps/mem" "github.com/influxdb/tivan/plugins/system/ps/net" ) @@ -17,6 +18,8 @@ type PS interface { DiskUsage() ([]*disk.DiskUsageStat, error) NetIO() ([]net.NetIOCountersStat, error) DiskIO() (map[string]disk.DiskIOCountersStat, error) + VMStat() (*mem.VirtualMemoryStat, error) + SwapStat() (*mem.SwapMemoryStat, error) } type SystemStats struct { @@ -116,6 +119,43 @@ func (s *SystemStats) Gather(acc plugins.Accumulator) error { acc.Add("drop_out", io.Dropout, tags) } + vm, err := s.ps.VMStat() + if err != nil { + return err + } + + vmtags := map[string]string{ + "memory": "virtual", + } + + acc.Add("total", vm.Total, vmtags) + acc.Add("available", vm.Available, vmtags) + acc.Add("used", vm.Used, vmtags) + acc.Add("used_prec", vm.UsedPercent, vmtags) + acc.Add("free", vm.Free, vmtags) + acc.Add("active", vm.Active, vmtags) + acc.Add("inactive", vm.Inactive, vmtags) + acc.Add("buffers", vm.Buffers, vmtags) + acc.Add("cached", vm.Cached, vmtags) + acc.Add("wired", vm.Wired, vmtags) + acc.Add("shared", vm.Shared, vmtags) + + swap, err := s.ps.SwapStat() + if err != nil { + return err + } + + swaptags := map[string]string{ + "memory": "swap", + } + + acc.Add("total", swap.Total, swaptags) + acc.Add("used", swap.Used, swaptags) + acc.Add("free", swap.Free, swaptags) + acc.Add("used_perc", swap.UsedPercent, swaptags) + acc.Add("swap_in", swap.Sin, swaptags) + acc.Add("swap_out", swap.Sout, swaptags) + return nil } @@ -162,6 +202,14 @@ func (s *systemPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) { return m, err } +func (s *systemPS) VMStat() (*mem.VirtualMemoryStat, error) { + return mem.VirtualMemory() +} + +func (s *systemPS) SwapStat() (*mem.SwapMemoryStat, error) { + return mem.SwapMemory() +} + func init() { plugins.Add("system", func() plugins.Plugin { return &SystemStats{ps: &systemPS{}} diff --git a/plugins/system/system_test.go b/plugins/system/system_test.go index 56fdf9d60..5c002d7a5 100644 --- a/plugins/system/system_test.go +++ b/plugins/system/system_test.go @@ -6,6 +6,7 @@ import ( "github.com/influxdb/tivan/plugins/system/ps/cpu" "github.com/influxdb/tivan/plugins/system/ps/disk" "github.com/influxdb/tivan/plugins/system/ps/load" + "github.com/influxdb/tivan/plugins/system/ps/mem" "github.com/influxdb/tivan/plugins/system/ps/net" "github.com/influxdb/tivan/testutil" "github.com/stretchr/testify/assert" @@ -84,6 +85,33 @@ func TestSystemStats_GenerateStats(t *testing.T) { mps.On("NetIO").Return([]net.NetIOCountersStat{netio}, nil) + vms := &mem.VirtualMemoryStat{ + Total: 12400, + Available: 7600, + Used: 5000, + UsedPercent: 47.1, + Free: 1235, + Active: 8134, + Inactive: 1124, + Buffers: 771, + Cached: 4312, + Wired: 134, + Shared: 2142, + } + + mps.On("VMStat").Return(vms, nil) + + sms := &mem.SwapMemoryStat{ + Total: 8123, + Used: 1232, + Free: 6412, + UsedPercent: 12.2, + Sin: 7, + Sout: 830, + } + + mps.On("SwapStat").Return(sms, nil) + err := ss.Gather(&acc) require.NoError(t, err) @@ -139,4 +167,32 @@ func TestSystemStats_GenerateStats(t *testing.T) { assert.True(t, acc.CheckTaggedValue("read_time", uint64(7123), dtags)) assert.True(t, acc.CheckTaggedValue("write_time", uint64(9087), dtags)) assert.True(t, acc.CheckTaggedValue("io_time", uint64(123552), dtags)) + + vmtags := map[string]string{ + "memory": "virtual", + } + + assert.NoError(t, acc.ValidateTaggedValue("total", uint64(12400), vmtags)) + assert.True(t, acc.CheckTaggedValue("total", uint64(12400), vmtags)) + assert.True(t, acc.CheckTaggedValue("available", uint64(7600), vmtags)) + assert.True(t, acc.CheckTaggedValue("used", uint64(5000), vmtags)) + assert.True(t, acc.CheckTaggedValue("used_prec", float64(47.1), vmtags)) + assert.True(t, acc.CheckTaggedValue("free", uint64(1235), vmtags)) + assert.True(t, acc.CheckTaggedValue("active", uint64(8134), vmtags)) + assert.True(t, acc.CheckTaggedValue("inactive", uint64(1124), vmtags)) + assert.True(t, acc.CheckTaggedValue("buffers", uint64(771), vmtags)) + assert.True(t, acc.CheckTaggedValue("cached", uint64(4312), vmtags)) + assert.True(t, acc.CheckTaggedValue("wired", uint64(134), vmtags)) + assert.True(t, acc.CheckTaggedValue("shared", uint64(2142), vmtags)) + + swaptags := map[string]string{ + "memory": "swap", + } + + assert.True(t, acc.CheckTaggedValue("total", uint64(8123), swaptags)) + assert.True(t, acc.CheckTaggedValue("used", uint64(1232), swaptags)) + assert.True(t, acc.CheckTaggedValue("used_perc", float64(12.2), swaptags)) + assert.True(t, acc.CheckTaggedValue("free", uint64(6412), swaptags)) + assert.True(t, acc.CheckTaggedValue("swap_in", uint64(7), swaptags)) + assert.True(t, acc.CheckTaggedValue("swap_out", uint64(830), swaptags)) } diff --git a/testutil/accumulator.go b/testutil/accumulator.go index a7967576a..6d048d109 100644 --- a/testutil/accumulator.go +++ b/testutil/accumulator.go @@ -1,5 +1,7 @@ package testutil +import "fmt" + type Point struct { Name string Value interface{} @@ -11,6 +13,8 @@ type Accumulator struct { } func (a *Accumulator) Add(name string, value interface{}, tags map[string]string) { + fmt.Printf("Add: %s => %v (%#v)\n", name, value, tags) + a.Points = append(a.Points, &Point{name, value, tags}) } @@ -25,17 +29,32 @@ func (a *Accumulator) CheckValue(name string, val interface{}) bool { } func (a *Accumulator) CheckTaggedValue(name string, val interface{}, tags map[string]string) bool { + return a.ValidateTaggedValue(name, val, tags) == nil +} + +func (a *Accumulator) ValidateTaggedValue(name string, val interface{}, tags map[string]string) error { for _, p := range a.Points { - for k, v := range p.Tags { - if tags[k] != v { - continue + var found bool + + if p.Tags == nil && tags == nil { + found = true + } else { + for k, v := range p.Tags { + if tags[k] == v { + found = true + break + } } } - if p.Name == name { - return p.Value == val + if found && p.Name == name { + if p.Value != val { + return fmt.Errorf("%v (%T) != %v (%T)", p.Value, p.Value, val, val) + } + + return nil } } - return false + return fmt.Errorf("unknown value %s with tags %v", name, tags) }