2015-05-18 23:01:42 +00:00
|
|
|
package system
|
|
|
|
|
|
|
|
import (
|
|
|
|
gonet "net"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
dc "github.com/fsouza/go-dockerclient"
|
2015-05-22 23:45:14 +00:00
|
|
|
"github.com/influxdb/telegraf/plugins"
|
|
|
|
"github.com/influxdb/telegraf/plugins/system/ps/common"
|
|
|
|
"github.com/influxdb/telegraf/plugins/system/ps/cpu"
|
|
|
|
"github.com/influxdb/telegraf/plugins/system/ps/disk"
|
|
|
|
"github.com/influxdb/telegraf/plugins/system/ps/docker"
|
|
|
|
"github.com/influxdb/telegraf/plugins/system/ps/load"
|
|
|
|
"github.com/influxdb/telegraf/plugins/system/ps/mem"
|
|
|
|
"github.com/influxdb/telegraf/plugins/system/ps/net"
|
2015-05-18 23:01:42 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type DockerContainerStat struct {
|
|
|
|
Id string
|
|
|
|
Name string
|
|
|
|
Command string
|
|
|
|
CPU *cpu.CPUTimesStat
|
|
|
|
Mem *docker.CgroupMemStat
|
|
|
|
}
|
|
|
|
|
|
|
|
type PS interface {
|
|
|
|
LoadAvg() (*load.LoadAvgStat, error)
|
2015-08-13 17:27:24 +00:00
|
|
|
CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error)
|
2015-05-18 23:01:42 +00:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
2015-08-13 17:27:24 +00:00
|
|
|
func (s *systemPS) CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error) {
|
|
|
|
var cpuTimes []cpu.CPUTimesStat
|
|
|
|
if perCPU {
|
|
|
|
if perCPUTimes, err := cpu.CPUTimes(true); err == nil {
|
|
|
|
cpuTimes = append(cpuTimes, perCPUTimes...)
|
|
|
|
} else {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if totalCPU {
|
|
|
|
if totalCPUTimes, err := cpu.CPUTimes(false); err == nil {
|
|
|
|
cpuTimes = append(cpuTimes, totalCPUTimes...)
|
|
|
|
} else {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cpuTimes, nil
|
2015-05-18 23:01:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2015-08-10 19:43:15 +00:00
|
|
|
du.Fstype = p.Fstype
|
2015-05-18 23:01:42 +00:00
|
|
|
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
|
|
|
|
}
|