From 5e6d33a57fe5bfcd2514d52368b3262571ed0c44 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Mon, 18 May 2015 16:01:42 -0700 Subject: [PATCH] Breakup the system plugin --- plugins/system/cpu.go | 50 ++++ plugins/system/disk.go | 83 +++++++ plugins/system/docker.go | 82 +++++++ plugins/system/memory.go | 78 +++++++ plugins/system/net.go | 88 +++++++ plugins/system/ps.go | 143 ++++++++++++ plugins/system/system.go | 478 +-------------------------------------- 7 files changed, 525 insertions(+), 477 deletions(-) create mode 100644 plugins/system/cpu.go create mode 100644 plugins/system/disk.go create mode 100644 plugins/system/docker.go create mode 100644 plugins/system/memory.go create mode 100644 plugins/system/net.go create mode 100644 plugins/system/ps.go diff --git a/plugins/system/cpu.go b/plugins/system/cpu.go new file mode 100644 index 000000000..41b16b534 --- /dev/null +++ b/plugins/system/cpu.go @@ -0,0 +1,50 @@ +package system + +import ( + "fmt" + + "github.com/influxdb/tivan/plugins" +) + +type CPUStats struct { + ps PS +} + +func (_ *CPUStats) Description() string { + return "Read metrics about cpu usage" +} + +func (_ *CPUStats) SampleConfig() string { return "" } + +func (s *CPUStats) Gather(acc plugins.Accumulator) error { + times, err := s.ps.CPUTimes() + if err != nil { + return fmt.Errorf("error getting CPU info: %s", err) + } + + for _, cts := range times { + tags := map[string]string{ + "cpu": cts.CPU, + } + + add(acc, "user", cts.User, tags) + add(acc, "system", cts.System, tags) + add(acc, "idle", cts.Idle, tags) + add(acc, "nice", cts.Nice, tags) + add(acc, "iowait", cts.Iowait, tags) + add(acc, "irq", cts.Irq, tags) + add(acc, "softirq", cts.Softirq, tags) + add(acc, "steal", cts.Steal, tags) + add(acc, "guest", cts.Guest, tags) + add(acc, "guestNice", cts.GuestNice, tags) + add(acc, "stolen", cts.Stolen, tags) + } + + return nil +} + +func init() { + plugins.Add("cpu", func() plugins.Plugin { + return &CPUStats{ps: &systemPS{}} + }) +} diff --git a/plugins/system/disk.go b/plugins/system/disk.go new file mode 100644 index 000000000..b19f226e0 --- /dev/null +++ b/plugins/system/disk.go @@ -0,0 +1,83 @@ +package system + +import ( + "fmt" + + "github.com/influxdb/tivan/plugins" +) + +type DiskStats struct { + ps PS +} + +func (_ *DiskStats) Description() string { + return "Read metrics about disk usage by mount point" +} + +func (_ *DiskStats) SampleConfig() string { return "" } + +func (s *DiskStats) Gather(acc plugins.Accumulator) error { + disks, err := s.ps.DiskUsage() + if err != nil { + return fmt.Errorf("error getting disk usage info: %s", err) + } + + for _, du := range disks { + tags := map[string]string{ + "path": du.Path, + } + + acc.Add("total", du.Total, tags) + acc.Add("free", du.Free, tags) + acc.Add("used", du.Total-du.Free, tags) + acc.Add("inodes_total", du.InodesTotal, tags) + acc.Add("inodes_free", du.InodesFree, tags) + acc.Add("inodes_used", du.InodesTotal-du.InodesFree, tags) + } + + return nil +} + +type DiskIOStats struct { + ps PS +} + +func (_ *DiskIOStats) Description() string { + return "Read metrics about disk IO by device" +} + +func (_ *DiskIOStats) SampleConfig() string { return "" } + +func (s *DiskIOStats) Gather(acc plugins.Accumulator) error { + diskio, err := s.ps.DiskIO() + if err != nil { + return fmt.Errorf("error getting disk io info: %s", err) + } + + for _, io := range diskio { + tags := map[string]string{ + "name": io.Name, + "serial": io.SerialNumber, + } + + acc.Add("reads", io.ReadCount, tags) + acc.Add("writes", io.WriteCount, tags) + acc.Add("read_bytes", io.ReadBytes, tags) + acc.Add("write_bytes", io.WriteBytes, tags) + acc.Add("read_time", io.ReadTime, tags) + acc.Add("write_time", io.WriteTime, tags) + acc.Add("io_time", io.IoTime, tags) + } + + return nil +} + +func init() { + plugins.Add("disk", func() plugins.Plugin { + return &DiskStats{ps: &systemPS{}} + }) + + plugins.Add("io", func() plugins.Plugin { + return &DiskIOStats{ps: &systemPS{}} + }) +} diff --git a/plugins/system/docker.go b/plugins/system/docker.go new file mode 100644 index 000000000..c939b5f51 --- /dev/null +++ b/plugins/system/docker.go @@ -0,0 +1,82 @@ +package system + +import ( + "fmt" + + "github.com/influxdb/tivan/plugins" +) + +type DockerStats struct { + ps PS +} + +func (_ *DockerStats) Description() string { + return "Read metrics about docker containers" +} + +func (_ *DockerStats) SampleConfig() string { return "" } + +func (s *DockerStats) Gather(acc plugins.Accumulator) error { + containers, err := s.ps.DockerStat() + if err != nil { + return fmt.Errorf("error getting docker info: %s", err) + } + + for _, cont := range containers { + tags := map[string]string{ + "id": cont.Id, + "name": cont.Name, + "command": cont.Command, + } + + cts := cont.CPU + + acc.Add("user", cts.User, tags) + acc.Add("system", cts.System, tags) + acc.Add("idle", cts.Idle, tags) + acc.Add("nice", cts.Nice, tags) + acc.Add("iowait", cts.Iowait, tags) + acc.Add("irq", cts.Irq, tags) + acc.Add("softirq", cts.Softirq, tags) + acc.Add("steal", cts.Steal, tags) + acc.Add("guest", cts.Guest, tags) + acc.Add("guestNice", cts.GuestNice, tags) + acc.Add("stolen", cts.Stolen, tags) + + acc.Add("cache", cont.Mem.Cache, tags) + acc.Add("rss", cont.Mem.RSS, tags) + acc.Add("rss_huge", cont.Mem.RSSHuge, tags) + acc.Add("mapped_file", cont.Mem.MappedFile, tags) + acc.Add("swap_in", cont.Mem.Pgpgin, tags) + acc.Add("swap_out", cont.Mem.Pgpgout, tags) + acc.Add("page_fault", cont.Mem.Pgfault, tags) + acc.Add("page_major_fault", cont.Mem.Pgmajfault, tags) + acc.Add("inactive_anon", cont.Mem.InactiveAnon, tags) + acc.Add("active_anon", cont.Mem.ActiveAnon, tags) + acc.Add("inactive_file", cont.Mem.InactiveFile, tags) + acc.Add("active_file", cont.Mem.ActiveFile, tags) + acc.Add("unevictable", cont.Mem.Unevictable, tags) + acc.Add("memory_limit", cont.Mem.HierarchicalMemoryLimit, tags) + acc.Add("total_cache", cont.Mem.TotalCache, tags) + acc.Add("total_rss", cont.Mem.TotalRSS, tags) + acc.Add("total_rss_huge", cont.Mem.TotalRSSHuge, tags) + acc.Add("total_mapped_file", cont.Mem.TotalMappedFile, tags) + acc.Add("total_swap_in", cont.Mem.TotalPgpgIn, tags) + acc.Add("total_swap_out", cont.Mem.TotalPgpgOut, tags) + acc.Add("total_page_fault", cont.Mem.TotalPgFault, tags) + acc.Add("total_page_major_fault", cont.Mem.TotalPgMajFault, tags) + acc.Add("total_inactive_anon", cont.Mem.TotalInactiveAnon, tags) + acc.Add("total_active_anon", cont.Mem.TotalActiveAnon, tags) + acc.Add("total_inactive_file", cont.Mem.TotalInactiveFile, tags) + acc.Add("total_active_file", cont.Mem.TotalActiveFile, tags) + acc.Add("total_unevictable", cont.Mem.TotalUnevictable, tags) + } + + return nil +} + +func init() { + plugins.Add("docker", func() plugins.Plugin { + return &DockerStats{ps: &systemPS{}} + }) +} diff --git a/plugins/system/memory.go b/plugins/system/memory.go new file mode 100644 index 000000000..890edd107 --- /dev/null +++ b/plugins/system/memory.go @@ -0,0 +1,78 @@ +package system + +import ( + "fmt" + + "github.com/influxdb/tivan/plugins" +) + +type MemStats struct { + ps PS +} + +func (_ *MemStats) Description() string { + return "Read metrics about memory usage" +} + +func (_ *MemStats) SampleConfig() string { return "" } + +func (s *MemStats) Gather(acc plugins.Accumulator) error { + vm, err := s.ps.VMStat() + if err != nil { + return fmt.Errorf("error getting virtual memory info: %s", err) + } + + vmtags := map[string]string(nil) + + 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) + + return nil +} + +type SwapStats struct { + ps PS +} + +func (_ *SwapStats) Description() string { + return "Read metrics about swap memory usage" +} + +func (_ *SwapStats) SampleConfig() string { return "" } + +func (s *SwapStats) Gather(acc plugins.Accumulator) error { + swap, err := s.ps.SwapStat() + if err != nil { + return fmt.Errorf("error getting swap memory info: %s", err) + } + + swaptags := map[string]string(nil) + + 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("in", swap.Sin, swaptags) + acc.Add("out", swap.Sout, swaptags) + + return nil +} + +func init() { + plugins.Add("mem", func() plugins.Plugin { + return &MemStats{ps: &systemPS{}} + }) + + plugins.Add("swap", func() plugins.Plugin { + return &SwapStats{ps: &systemPS{}} + }) +} diff --git a/plugins/system/net.go b/plugins/system/net.go new file mode 100644 index 000000000..b7dc3637a --- /dev/null +++ b/plugins/system/net.go @@ -0,0 +1,88 @@ +package system + +import ( + "fmt" + "net" + + "github.com/influxdb/tivan/plugins" +) + +type NetIOStats struct { + ps PS + + Interfaces []string +} + +func (_ *NetIOStats) Description() string { + return "Read metrics about network interface usage" +} + +var netSampleConfig = ` +# By default, tivan gathers stats from any up interface (excluding loopback) +# Setting interfaces will tell it to gather these explicit interfaces, +# regardless of status. +# +# interfaces = ["eth0", ... ] +` + +func (_ *NetIOStats) SampleConfig() string { + return netSampleConfig +} + +func (s *NetIOStats) Gather(acc plugins.Accumulator) error { + netio, err := s.ps.NetIO() + if err != nil { + return fmt.Errorf("error getting net io info: %s", err) + } + + for _, io := range netio { + if len(s.Interfaces) != 0 { + var found bool + + for _, name := range s.Interfaces { + if name == io.Name { + found = true + break + } + } + + if !found { + continue + } + } else { + iface, err := net.InterfaceByName(io.Name) + if err != nil { + continue + } + + if iface.Flags&net.FlagLoopback == net.FlagLoopback { + continue + } + + if iface.Flags&net.FlagUp == 0 { + continue + } + } + + tags := map[string]string{ + "interface": io.Name, + } + + acc.Add("bytes_sent", io.BytesSent, tags) + acc.Add("bytes_recv", io.BytesRecv, tags) + acc.Add("packets_sent", io.PacketsSent, tags) + acc.Add("packets_recv", io.PacketsRecv, tags) + acc.Add("err_in", io.Errin, tags) + acc.Add("err_out", io.Errout, tags) + acc.Add("drop_in", io.Dropin, tags) + acc.Add("drop_out", io.Dropout, tags) + } + + return nil +} + +func init() { + plugins.Add("net", func() plugins.Plugin { + return &NetIOStats{ps: &systemPS{}} + }) +} diff --git a/plugins/system/ps.go b/plugins/system/ps.go new file mode 100644 index 000000000..0cbb1c9c6 --- /dev/null +++ b/plugins/system/ps.go @@ -0,0 +1,143 @@ +package system + +import ( + gonet "net" + "strings" + + dc "github.com/fsouza/go-dockerclient" + "github.com/influxdb/tivan/plugins" + "github.com/influxdb/tivan/plugins/system/ps/common" + "github.com/influxdb/tivan/plugins/system/ps/cpu" + "github.com/influxdb/tivan/plugins/system/ps/disk" + "github.com/influxdb/tivan/plugins/system/ps/docker" + "github.com/influxdb/tivan/plugins/system/ps/load" + "github.com/influxdb/tivan/plugins/system/ps/mem" + "github.com/influxdb/tivan/plugins/system/ps/net" +) + +type DockerContainerStat struct { + Id string + Name string + Command string + CPU *cpu.CPUTimesStat + Mem *docker.CgroupMemStat +} + +type PS interface { + LoadAvg() (*load.LoadAvgStat, error) + CPUTimes() ([]cpu.CPUTimesStat, error) + DiskUsage() ([]*disk.DiskUsageStat, error) + NetIO() ([]net.NetIOCountersStat, error) + DiskIO() (map[string]disk.DiskIOCountersStat, error) + VMStat() (*mem.VirtualMemoryStat, error) + SwapStat() (*mem.SwapMemoryStat, error) + DockerStat() ([]*DockerContainerStat, error) +} + +func add(acc plugins.Accumulator, + name string, val float64, tags map[string]string) { + if val >= 0 { + acc.Add(name, val, tags) + } +} + +type systemPS struct { + dockerClient *dc.Client +} + +func (s *systemPS) LoadAvg() (*load.LoadAvgStat, error) { + return load.LoadAvg() +} + +func (s *systemPS) CPUTimes() ([]cpu.CPUTimesStat, error) { + return cpu.CPUTimes(true) +} + +func (s *systemPS) DiskUsage() ([]*disk.DiskUsageStat, error) { + parts, err := disk.DiskPartitions(true) + if err != nil { + return nil, err + } + + var usage []*disk.DiskUsageStat + + for _, p := range parts { + du, err := disk.DiskUsage(p.Mountpoint) + if err != nil { + return nil, err + } + + usage = append(usage, du) + } + + return usage, nil +} + +func (s *systemPS) NetIO() ([]net.NetIOCountersStat, error) { + return net.NetIOCounters(true) +} + +func (s *systemPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) { + m, err := disk.DiskIOCounters() + if err == common.NotImplementedError { + return nil, nil + } + + return m, err +} + +func (s *systemPS) VMStat() (*mem.VirtualMemoryStat, error) { + return mem.VirtualMemory() +} + +func (s *systemPS) SwapStat() (*mem.SwapMemoryStat, error) { + return mem.SwapMemory() +} + +func (s *systemPS) DockerStat() ([]*DockerContainerStat, error) { + if s.dockerClient == nil { + c, err := dc.NewClient("unix:///var/run/docker.sock") + if err != nil { + return nil, err + } + + s.dockerClient = c + } + + opts := dc.ListContainersOptions{} + + list, err := s.dockerClient.ListContainers(opts) + if err != nil { + if _, ok := err.(*gonet.OpError); ok { + return nil, nil + } + + return nil, err + } + + var stats []*DockerContainerStat + + for _, cont := range list { + ctu, err := docker.CgroupCPUDocker(cont.ID) + if err != nil { + return nil, err + } + + mem, err := docker.CgroupMemDocker(cont.ID) + if err != nil { + return nil, err + } + + name := strings.Join(cont.Names, " ") + + stats = append(stats, &DockerContainerStat{ + Id: cont.ID, + Name: name, + Command: cont.Command, + CPU: ctu, + Mem: mem, + }) + } + + return stats, nil +} diff --git a/plugins/system/system.go b/plugins/system/system.go index 9f49832f3..281b6dac2 100644 --- a/plugins/system/system.go +++ b/plugins/system/system.go @@ -1,353 +1,6 @@ package system -import ( - "fmt" - gonet "net" - "strings" - - dc "github.com/fsouza/go-dockerclient" - "github.com/influxdb/tivan/plugins" - "github.com/influxdb/tivan/plugins/system/ps/common" - "github.com/influxdb/tivan/plugins/system/ps/cpu" - "github.com/influxdb/tivan/plugins/system/ps/disk" - "github.com/influxdb/tivan/plugins/system/ps/docker" - "github.com/influxdb/tivan/plugins/system/ps/load" - "github.com/influxdb/tivan/plugins/system/ps/mem" - "github.com/influxdb/tivan/plugins/system/ps/net" -) - -type DockerContainerStat struct { - Id string - Name string - Command string - CPU *cpu.CPUTimesStat - Mem *docker.CgroupMemStat -} - -type PS interface { - LoadAvg() (*load.LoadAvgStat, error) - CPUTimes() ([]cpu.CPUTimesStat, error) - DiskUsage() ([]*disk.DiskUsageStat, error) - NetIO() ([]net.NetIOCountersStat, error) - DiskIO() (map[string]disk.DiskIOCountersStat, error) - VMStat() (*mem.VirtualMemoryStat, error) - SwapStat() (*mem.SwapMemoryStat, error) - DockerStat() ([]*DockerContainerStat, error) -} - -func add(acc plugins.Accumulator, - name string, val float64, tags map[string]string) { - if val >= 0 { - acc.Add(name, val, tags) - } -} - -type CPUStats struct { - ps PS -} - -func (_ *CPUStats) Description() string { - return "Read metrics about cpu usage" -} - -func (_ *CPUStats) SampleConfig() string { return "" } - -func (s *CPUStats) Gather(acc plugins.Accumulator) error { - times, err := s.ps.CPUTimes() - if err != nil { - return fmt.Errorf("error getting CPU info: %s", err) - } - - for _, cts := range times { - tags := map[string]string{ - "cpu": cts.CPU, - } - - add(acc, "user", cts.User, tags) - add(acc, "system", cts.System, tags) - add(acc, "idle", cts.Idle, tags) - add(acc, "nice", cts.Nice, tags) - add(acc, "iowait", cts.Iowait, tags) - add(acc, "irq", cts.Irq, tags) - add(acc, "softirq", cts.Softirq, tags) - add(acc, "steal", cts.Steal, tags) - add(acc, "guest", cts.Guest, tags) - add(acc, "guestNice", cts.GuestNice, tags) - add(acc, "stolen", cts.Stolen, tags) - } - - return nil -} - -type DiskStats struct { - ps PS -} - -func (_ *DiskStats) Description() string { - return "Read metrics about disk usage by mount point" -} - -func (_ *DiskStats) SampleConfig() string { return "" } - -func (s *DiskStats) Gather(acc plugins.Accumulator) error { - disks, err := s.ps.DiskUsage() - if err != nil { - return fmt.Errorf("error getting disk usage info: %s", err) - } - - for _, du := range disks { - tags := map[string]string{ - "path": du.Path, - } - - acc.Add("total", du.Total, tags) - acc.Add("free", du.Free, tags) - acc.Add("used", du.Total-du.Free, tags) - acc.Add("inodes_total", du.InodesTotal, tags) - acc.Add("inodes_free", du.InodesFree, tags) - acc.Add("inodes_used", du.InodesTotal-du.InodesFree, tags) - } - - return nil -} - -type DiskIOStats struct { - ps PS -} - -func (_ *DiskIOStats) Description() string { - return "Read metrics about disk IO by device" -} - -func (_ *DiskIOStats) SampleConfig() string { return "" } - -func (s *DiskIOStats) Gather(acc plugins.Accumulator) error { - diskio, err := s.ps.DiskIO() - if err != nil { - return fmt.Errorf("error getting disk io info: %s", err) - } - - for _, io := range diskio { - tags := map[string]string{ - "name": io.Name, - "serial": io.SerialNumber, - } - - acc.Add("reads", io.ReadCount, tags) - acc.Add("writes", io.WriteCount, tags) - acc.Add("read_bytes", io.ReadBytes, tags) - acc.Add("write_bytes", io.WriteBytes, tags) - acc.Add("read_time", io.ReadTime, tags) - acc.Add("write_time", io.WriteTime, tags) - acc.Add("io_time", io.IoTime, tags) - } - - return nil -} - -type NetIOStats struct { - ps PS - - Interfaces []string -} - -func (_ *NetIOStats) Description() string { - return "Read metrics about network interface usage" -} - -var netSampleConfig = ` -# By default, tivan gathers stats from any up interface (excluding loopback) -# Setting interfaces will tell it to gather these explicit interfaces, -# regardless of status. -# -# interfaces = ["eth0", ... ] -` - -func (_ *NetIOStats) SampleConfig() string { - return netSampleConfig -} - -func (s *NetIOStats) Gather(acc plugins.Accumulator) error { - netio, err := s.ps.NetIO() - if err != nil { - return fmt.Errorf("error getting net io info: %s", err) - } - - for _, io := range netio { - if len(s.Interfaces) != 0 { - var found bool - - for _, name := range s.Interfaces { - if name == io.Name { - found = true - break - } - } - - if !found { - continue - } - } else { - iface, err := gonet.InterfaceByName(io.Name) - if err != nil { - continue - } - - if iface.Flags&gonet.FlagLoopback == gonet.FlagLoopback { - continue - } - - if iface.Flags&gonet.FlagUp == 0 { - continue - } - } - - tags := map[string]string{ - "interface": io.Name, - } - - acc.Add("bytes_sent", io.BytesSent, tags) - acc.Add("bytes_recv", io.BytesRecv, tags) - acc.Add("packets_sent", io.PacketsSent, tags) - acc.Add("packets_recv", io.PacketsRecv, tags) - acc.Add("err_in", io.Errin, tags) - acc.Add("err_out", io.Errout, tags) - acc.Add("drop_in", io.Dropin, tags) - acc.Add("drop_out", io.Dropout, tags) - } - - return nil -} - -type MemStats struct { - ps PS -} - -func (_ *MemStats) Description() string { - return "Read metrics about memory usage" -} - -func (_ *MemStats) SampleConfig() string { return "" } - -func (s *MemStats) Gather(acc plugins.Accumulator) error { - vm, err := s.ps.VMStat() - if err != nil { - return fmt.Errorf("error getting virtual memory info: %s", err) - } - - vmtags := map[string]string(nil) - - 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) - - return nil -} - -type SwapStats struct { - ps PS -} - -func (_ *SwapStats) Description() string { - return "Read metrics about swap memory usage" -} - -func (_ *SwapStats) SampleConfig() string { return "" } - -func (s *SwapStats) Gather(acc plugins.Accumulator) error { - swap, err := s.ps.SwapStat() - if err != nil { - return fmt.Errorf("error getting swap memory info: %s", err) - } - - swaptags := map[string]string(nil) - - 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("in", swap.Sin, swaptags) - acc.Add("out", swap.Sout, swaptags) - - return nil -} - -type DockerStats struct { - ps PS -} - -func (_ *DockerStats) Description() string { - return "Read metrics about docker containers" -} - -func (_ *DockerStats) SampleConfig() string { return "" } - -func (s *DockerStats) Gather(acc plugins.Accumulator) error { - containers, err := s.ps.DockerStat() - if err != nil { - return fmt.Errorf("error getting docker info: %s", err) - } - - for _, cont := range containers { - tags := map[string]string{ - "id": cont.Id, - "name": cont.Name, - "command": cont.Command, - } - - cts := cont.CPU - - acc.Add("user", cts.User, tags) - acc.Add("system", cts.System, tags) - acc.Add("idle", cts.Idle, tags) - acc.Add("nice", cts.Nice, tags) - acc.Add("iowait", cts.Iowait, tags) - acc.Add("irq", cts.Irq, tags) - acc.Add("softirq", cts.Softirq, tags) - acc.Add("steal", cts.Steal, tags) - acc.Add("guest", cts.Guest, tags) - acc.Add("guestNice", cts.GuestNice, tags) - acc.Add("stolen", cts.Stolen, tags) - - acc.Add("cache", cont.Mem.Cache, tags) - acc.Add("rss", cont.Mem.RSS, tags) - acc.Add("rss_huge", cont.Mem.RSSHuge, tags) - acc.Add("mapped_file", cont.Mem.MappedFile, tags) - acc.Add("swap_in", cont.Mem.Pgpgin, tags) - acc.Add("swap_out", cont.Mem.Pgpgout, tags) - acc.Add("page_fault", cont.Mem.Pgfault, tags) - acc.Add("page_major_fault", cont.Mem.Pgmajfault, tags) - acc.Add("inactive_anon", cont.Mem.InactiveAnon, tags) - acc.Add("active_anon", cont.Mem.ActiveAnon, tags) - acc.Add("inactive_file", cont.Mem.InactiveFile, tags) - acc.Add("active_file", cont.Mem.ActiveFile, tags) - acc.Add("unevictable", cont.Mem.Unevictable, tags) - acc.Add("memory_limit", cont.Mem.HierarchicalMemoryLimit, tags) - acc.Add("total_cache", cont.Mem.TotalCache, tags) - acc.Add("total_rss", cont.Mem.TotalRSS, tags) - acc.Add("total_rss_huge", cont.Mem.TotalRSSHuge, tags) - acc.Add("total_mapped_file", cont.Mem.TotalMappedFile, tags) - acc.Add("total_swap_in", cont.Mem.TotalPgpgIn, tags) - acc.Add("total_swap_out", cont.Mem.TotalPgpgOut, tags) - acc.Add("total_page_fault", cont.Mem.TotalPgFault, tags) - acc.Add("total_page_major_fault", cont.Mem.TotalPgMajFault, tags) - acc.Add("total_inactive_anon", cont.Mem.TotalInactiveAnon, tags) - acc.Add("total_active_anon", cont.Mem.TotalActiveAnon, tags) - acc.Add("total_inactive_file", cont.Mem.TotalInactiveFile, tags) - acc.Add("total_active_file", cont.Mem.TotalActiveFile, tags) - acc.Add("total_unevictable", cont.Mem.TotalUnevictable, tags) - } - - return nil -} +import "github.com/influxdb/tivan/plugins" type SystemStats struct { ps PS @@ -379,136 +32,7 @@ func (s *SystemStats) Gather(acc plugins.Accumulator) error { return nil } -type systemPS struct { - dockerClient *dc.Client -} - -func (s *systemPS) LoadAvg() (*load.LoadAvgStat, error) { - return load.LoadAvg() -} - -func (s *systemPS) CPUTimes() ([]cpu.CPUTimesStat, error) { - return cpu.CPUTimes(true) -} - -func (s *systemPS) DiskUsage() ([]*disk.DiskUsageStat, error) { - parts, err := disk.DiskPartitions(true) - if err != nil { - return nil, err - } - - var usage []*disk.DiskUsageStat - - for _, p := range parts { - du, err := disk.DiskUsage(p.Mountpoint) - if err != nil { - return nil, err - } - - usage = append(usage, du) - } - - return usage, nil -} - -func (s *systemPS) NetIO() ([]net.NetIOCountersStat, error) { - return net.NetIOCounters(true) -} - -func (s *systemPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) { - m, err := disk.DiskIOCounters() - if err == common.NotImplementedError { - return nil, nil - } - - return m, err -} - -func (s *systemPS) VMStat() (*mem.VirtualMemoryStat, error) { - return mem.VirtualMemory() -} - -func (s *systemPS) SwapStat() (*mem.SwapMemoryStat, error) { - return mem.SwapMemory() -} - -func (s *systemPS) DockerStat() ([]*DockerContainerStat, error) { - if s.dockerClient == nil { - c, err := dc.NewClient("unix:///var/run/docker.sock") - if err != nil { - return nil, err - } - - s.dockerClient = c - } - - opts := dc.ListContainersOptions{} - - list, err := s.dockerClient.ListContainers(opts) - if err != nil { - if _, ok := err.(*gonet.OpError); ok { - return nil, nil - } - - return nil, err - } - - var stats []*DockerContainerStat - - for _, cont := range list { - ctu, err := docker.CgroupCPUDocker(cont.ID) - if err != nil { - return nil, err - } - - mem, err := docker.CgroupMemDocker(cont.ID) - if err != nil { - return nil, err - } - - name := strings.Join(cont.Names, " ") - - stats = append(stats, &DockerContainerStat{ - Id: cont.ID, - Name: name, - Command: cont.Command, - CPU: ctu, - Mem: mem, - }) - } - - return stats, nil -} - func init() { - plugins.Add("cpu", func() plugins.Plugin { - return &CPUStats{ps: &systemPS{}} - }) - - plugins.Add("disk", func() plugins.Plugin { - return &DiskStats{ps: &systemPS{}} - }) - - plugins.Add("io", func() plugins.Plugin { - return &DiskIOStats{ps: &systemPS{}} - }) - - plugins.Add("net", func() plugins.Plugin { - return &NetIOStats{ps: &systemPS{}} - }) - - plugins.Add("mem", func() plugins.Plugin { - return &MemStats{ps: &systemPS{}} - }) - - plugins.Add("swap", func() plugins.Plugin { - return &SwapStats{ps: &systemPS{}} - }) - - plugins.Add("docker", func() plugins.Plugin { - return &DockerStats{ps: &systemPS{}} - }) - plugins.Add("system", func() plugins.Plugin { return &SystemStats{ps: &systemPS{}} })