Add VM and Swap stats

This commit is contained in:
Evan Phoenix 2015-04-06 14:53:43 -07:00
parent 250074eecf
commit b39b1958e8
4 changed files with 146 additions and 6 deletions

View File

@ -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/cpu"
import "github.com/influxdb/tivan/plugins/system/ps/disk" 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/load"
import "github.com/influxdb/tivan/plugins/system/ps/mem"
import "github.com/influxdb/tivan/plugins/system/ps/net" import "github.com/influxdb/tivan/plugins/system/ps/net"
type MockPS struct { type MockPS struct {
@ -51,3 +52,19 @@ func (m *MockPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) {
return r0, r1 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
}

View File

@ -8,6 +8,7 @@ import (
"github.com/influxdb/tivan/plugins/system/ps/cpu" "github.com/influxdb/tivan/plugins/system/ps/cpu"
"github.com/influxdb/tivan/plugins/system/ps/disk" "github.com/influxdb/tivan/plugins/system/ps/disk"
"github.com/influxdb/tivan/plugins/system/ps/load" "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/plugins/system/ps/net"
) )
@ -17,6 +18,8 @@ type PS interface {
DiskUsage() ([]*disk.DiskUsageStat, error) DiskUsage() ([]*disk.DiskUsageStat, error)
NetIO() ([]net.NetIOCountersStat, error) NetIO() ([]net.NetIOCountersStat, error)
DiskIO() (map[string]disk.DiskIOCountersStat, error) DiskIO() (map[string]disk.DiskIOCountersStat, error)
VMStat() (*mem.VirtualMemoryStat, error)
SwapStat() (*mem.SwapMemoryStat, error)
} }
type SystemStats struct { type SystemStats struct {
@ -116,6 +119,43 @@ func (s *SystemStats) Gather(acc plugins.Accumulator) error {
acc.Add("drop_out", io.Dropout, tags) 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 return nil
} }
@ -162,6 +202,14 @@ func (s *systemPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) {
return m, err 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() { func init() {
plugins.Add("system", func() plugins.Plugin { plugins.Add("system", func() plugins.Plugin {
return &SystemStats{ps: &systemPS{}} return &SystemStats{ps: &systemPS{}}

View File

@ -6,6 +6,7 @@ import (
"github.com/influxdb/tivan/plugins/system/ps/cpu" "github.com/influxdb/tivan/plugins/system/ps/cpu"
"github.com/influxdb/tivan/plugins/system/ps/disk" "github.com/influxdb/tivan/plugins/system/ps/disk"
"github.com/influxdb/tivan/plugins/system/ps/load" "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/plugins/system/ps/net"
"github.com/influxdb/tivan/testutil" "github.com/influxdb/tivan/testutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -84,6 +85,33 @@ func TestSystemStats_GenerateStats(t *testing.T) {
mps.On("NetIO").Return([]net.NetIOCountersStat{netio}, nil) 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) err := ss.Gather(&acc)
require.NoError(t, err) 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("read_time", uint64(7123), dtags))
assert.True(t, acc.CheckTaggedValue("write_time", uint64(9087), dtags)) assert.True(t, acc.CheckTaggedValue("write_time", uint64(9087), dtags))
assert.True(t, acc.CheckTaggedValue("io_time", uint64(123552), 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))
} }

View File

@ -1,5 +1,7 @@
package testutil package testutil
import "fmt"
type Point struct { type Point struct {
Name string Name string
Value interface{} Value interface{}
@ -11,6 +13,8 @@ type Accumulator struct {
} }
func (a *Accumulator) Add(name string, value interface{}, tags map[string]string) { 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}) 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 { 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 _, p := range a.Points {
for k, v := range p.Tags { var found bool
if tags[k] != v {
continue 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 { if found && p.Name == name {
return p.Value == val 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)
} }