Breakup the system plugin
This commit is contained in:
		
							parent
							
								
									66905c069f
								
							
						
					
					
						commit
						5e6d33a57f
					
				|  | @ -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{}} | ||||
| 	}) | ||||
| } | ||||
|  | @ -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{}} | ||||
| 	}) | ||||
| } | ||||
|  | @ -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{}} | ||||
| 	}) | ||||
| } | ||||
|  | @ -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{}} | ||||
| 	}) | ||||
| } | ||||
|  | @ -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{}} | ||||
| 	}) | ||||
| } | ||||
|  | @ -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 | ||||
| } | ||||
|  | @ -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{}} | ||||
| 	}) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue