From ee81917b2c7494707acaae60b21258c7f3929b99 Mon Sep 17 00:00:00 2001 From: Sean Chittenden Date: Fri, 17 Jun 2016 07:31:00 -0700 Subject: [PATCH 1/3] Update gopsutils --- vendor/github.com/shirou/gopsutil/cpu/cpu.go | 21 +++- .../shirou/gopsutil/cpu/cpu_darwin.go | 4 +- .../shirou/gopsutil/cpu/cpu_darwin_cgo.go | 2 + .../shirou/gopsutil/cpu/cpu_freebsd.go | 2 +- .../shirou/gopsutil/cpu/cpu_linux.go | 2 +- .../shirou/gopsutil/cpu/cpu_unix.go | 87 ++++++++++----- .../shirou/gopsutil/disk/disk_linux.go | 6 + .../github.com/shirou/gopsutil/host/host.go | 14 ++- .../shirou/gopsutil/host/host_darwin.go | 4 +- .../shirou/gopsutil/host/host_freebsd.go | 4 +- .../shirou/gopsutil/host/host_linux.go | 70 ++++++++++-- .../gopsutil/host/host_linux_ppc64le.go | 2 + .../shirou/gopsutil/host/host_windows.go | 14 +-- .../shirou/gopsutil/internal/common/common.go | 75 ++++++++++--- vendor/github.com/shirou/gopsutil/mem/mem.go | 8 ++ .../shirou/gopsutil/mem/mem_darwin_nocgo.go | 2 +- .../shirou/gopsutil/mem/mem_freebsd.go | 2 +- vendor/github.com/shirou/gopsutil/net/net.go | 13 ++- .../shirou/gopsutil/net/net_darwin.go | 2 +- .../shirou/gopsutil/net/net_freebsd.go | 2 +- .../shirou/gopsutil/net/net_linux.go | 10 ++ .../gopsutil/process/process_linux_arm64.go | 9 ++ .../shirou/gopsutil/process/process_posix.go | 7 +- .../gopsutil/process/process_windows.go | 103 +++++++++++++++--- .../gopsutil/process/process_windows_386.go | 16 +++ .../gopsutil/process/process_windows_amd64.go | 16 +++ vendor/vendor.json | 42 +++---- 27 files changed, 418 insertions(+), 121 deletions(-) create mode 100644 vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_windows_386.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu.go b/vendor/github.com/shirou/gopsutil/cpu/cpu.go index 71535094d..6f76b764c 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu.go @@ -5,6 +5,9 @@ import ( "runtime" "strconv" "strings" + "sync" + + "github.com/shirou/gopsutil/internal/common" ) type TimesStat struct { @@ -37,8 +40,22 @@ type InfoStat struct { Flags []string `json:"flags"` } -var lastCPUTimes []TimesStat -var lastPerCPUTimes []TimesStat +type lastPercent struct { + sync.Mutex + lastCPUTimes []TimesStat + lastPerCPUTimes []TimesStat +} + +var lastCPUPercent lastPercent +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} + lastCPUPercent.Lock() + lastCPUPercent.lastCPUTimes, _ = Times(false) + lastCPUPercent.lastPerCPUTimes, _ = Times(true) + lastCPUPercent.Unlock() +} func Counts(logical bool) (int, error) { return runtime.NumCPU(), nil diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go index fbb74a821..4cb1d8ca8 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go @@ -36,7 +36,7 @@ func Info() ([]InfoStat, error) { if err != nil { return ret, err } - out, err := exec.Command(sysctl, "machdep.cpu").Output() + out, err := invoke.Command(sysctl, "machdep.cpu") if err != nil { return ret, err } @@ -90,7 +90,7 @@ func Info() ([]InfoStat, error) { // Use the rated frequency of the CPU. This is a static value and does not // account for low power or Turbo Boost modes. - out, err = exec.Command(sysctl, "hw.cpufrequency").Output() + out, err = invoke.Command(sysctl, "hw.cpufrequency") if err != nil { return ret, err } diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go index ee59fefc0..d38dd627e 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go @@ -10,7 +10,9 @@ package cpu #include #include #include +#if TARGET_OS_MAC #include +#endif #include #include */ diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go index a536e503f..edc962788 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go @@ -27,7 +27,7 @@ func init() { if err != nil { return } - out, err := exec.Command(getconf, "CLK_TCK").Output() + out, err := invoke.Command(getconf, "CLK_TCK") // ignore errors if err == nil { i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go index 975b75c07..6df542bdb 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go @@ -19,7 +19,7 @@ func init() { if err != nil { return } - out, err := exec.Command(getconf, "CLK_TCK").Output() + out, err := invoke.Command(getconf, "CLK_TCK") // ignore errors if err == nil { i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go index 9f1ea4d77..0ed7d62ad 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go @@ -7,24 +7,46 @@ import ( "time" ) -func Percent(interval time.Duration, percpu bool) ([]float64, error) { - getAllBusy := func(t TimesStat) (float64, float64) { - busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + - t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen - return busy + t.Idle, busy +func getAllBusy(t TimesStat) (float64, float64) { + busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + + t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen + return busy + t.Idle, busy +} + +func calculateBusy(t1, t2 TimesStat) float64 { + t1All, t1Busy := getAllBusy(t1) + t2All, t2Busy := getAllBusy(t2) + + if t2Busy <= t1Busy { + return 0 + } + if t2All <= t1All { + return 1 + } + return (t2Busy - t1Busy) / (t2All - t1All) * 100 +} + +func calculateAllBusy(t1, t2 []TimesStat) ([]float64, error) { + // Make sure the CPU measurements have the same length. + if len(t1) != len(t2) { + return nil, fmt.Errorf( + "received two CPU counts: %d != %d", + len(t1), len(t2), + ) } - calculate := func(t1, t2 TimesStat) float64 { - t1All, t1Busy := getAllBusy(t1) - t2All, t2Busy := getAllBusy(t2) + ret := make([]float64, len(t1)) + for i, t := range t2 { + ret[i] = calculateBusy(t1[i], t) + } + return ret, nil +} - if t2Busy <= t1Busy { - return 0 - } - if t2All <= t1All { - return 1 - } - return (t2Busy - t1Busy) / (t2All - t1All) * 100 +//Percent calculates the percentage of cpu used either per CPU or combined. +//If an interval of 0 is given it will compare the current cpu times against the last call. +func Percent(interval time.Duration, percpu bool) ([]float64, error) { + if interval <= 0 { + return percentUsedFromLastCall(percpu) } // Get CPU usage at the start of the interval. @@ -33,9 +55,7 @@ func Percent(interval time.Duration, percpu bool) ([]float64, error) { return nil, err } - if interval > 0 { - time.Sleep(interval) - } + time.Sleep(interval) // And at the end of the interval. cpuTimes2, err := Times(percpu) @@ -43,17 +63,28 @@ func Percent(interval time.Duration, percpu bool) ([]float64, error) { return nil, err } - // Make sure the CPU measurements have the same length. - if len(cpuTimes1) != len(cpuTimes2) { - return nil, fmt.Errorf( - "received two CPU counts: %d != %d", - len(cpuTimes1), len(cpuTimes2), - ) + return calculateAllBusy(cpuTimes1, cpuTimes2) +} + +func percentUsedFromLastCall(percpu bool) ([]float64, error) { + cpuTimes, err := Times(percpu) + if err != nil { + return nil, err + } + lastCPUPercent.Lock() + defer lastCPUPercent.Unlock() + var lastTimes []TimesStat + if percpu { + lastTimes = lastCPUPercent.lastPerCPUTimes + lastCPUPercent.lastPerCPUTimes = cpuTimes + } else { + lastTimes = lastCPUPercent.lastCPUTimes + lastCPUPercent.lastCPUTimes = cpuTimes } - ret := make([]float64, len(cpuTimes1)) - for i, t := range cpuTimes2 { - ret[i] = calculate(cpuTimes1[i], t) + if lastTimes == nil { + return nil, fmt.Errorf("Error getting times for cpu percent. LastTimes was nil") } - return ret, nil + return calculateAllBusy(lastTimes, cpuTimes) + } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go index f581ef7aa..757becb72 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go @@ -283,6 +283,10 @@ func IOCounters() (map[string]IOCountersStat, error) { for _, line := range lines { fields := strings.Fields(line) + if len(fields) < 14 { + // malformed line in /proc/diskstats, avoid panic by ignoring. + continue + } name := fields[2] reads, err := strconv.ParseUint((fields[3]), 10, 64) if err != nil { @@ -332,6 +336,8 @@ func IOCounters() (map[string]IOCountersStat, error) { return ret, nil } +// GetDiskSerialNumber returns Serial Number of given device or empty string +// on error. Name of device is expected, eg. /dev/sda func GetDiskSerialNumber(name string) string { n := fmt.Sprintf("--name=%s", name) udevadm, err := exec.LookPath("/sbin/udevadm") diff --git a/vendor/github.com/shirou/gopsutil/host/host.go b/vendor/github.com/shirou/gopsutil/host/host.go index 150eb60a7..1a6545b99 100644 --- a/vendor/github.com/shirou/gopsutil/host/host.go +++ b/vendor/github.com/shirou/gopsutil/host/host.go @@ -2,17 +2,25 @@ package host import ( "encoding/json" + + "github.com/shirou/gopsutil/internal/common" ) +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} +} + // A HostInfoStat describes the host status. // This is not in the psutil but it useful. type InfoStat struct { Hostname string `json:"hostname"` Uptime uint64 `json:"uptime"` BootTime uint64 `json:"bootTime"` - Procs uint64 `json:"procs"` // number of processes - OS string `json:"os"` // ex: freebsd, linux - Platform string `json:"platform"` // ex: ubuntu, linuxmint + Procs uint64 `json:"procs"` // number of processes + OS string `json:"os"` // ex: freebsd, linux + Platform string `json:"platform"` // ex: ubuntu, linuxmint PlatformFamily string `json:"platformFamily"` // ex: debian, rhel PlatformVersion string `json:"platformVersion"` VirtualizationSystem string `json:"virtualizationSystem"` diff --git a/vendor/github.com/shirou/gopsutil/host/host_darwin.go b/vendor/github.com/shirou/gopsutil/host/host_darwin.go index f4a8c36a2..ec2dc2ce8 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_darwin.go +++ b/vendor/github.com/shirou/gopsutil/host/host_darwin.go @@ -131,12 +131,12 @@ func PlatformInformation() (string, string, string, error) { if err != nil { return "", "", "", err } - out, err := exec.Command(uname, "-s").Output() + out, err := invoke.Command(uname, "-s") if err == nil { platform = strings.ToLower(strings.TrimSpace(string(out))) } - out, err = exec.Command(uname, "-r").Output() + out, err = invoke.Command(uname, "-r") if err == nil { version = strings.ToLower(strings.TrimSpace(string(out))) } diff --git a/vendor/github.com/shirou/gopsutil/host/host_freebsd.go b/vendor/github.com/shirou/gopsutil/host/host_freebsd.go index aeb1b45a5..30206d200 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/host/host_freebsd.go @@ -136,12 +136,12 @@ func PlatformInformation() (string, string, string, error) { return "", "", "", err } - out, err := exec.Command(uname, "-s").Output() + out, err := invoke.Command(uname, "-s") if err == nil { platform = strings.ToLower(strings.TrimSpace(string(out))) } - out, err = exec.Command(uname, "-r").Output() + out, err = invoke.Command(uname, "-r") if err == nil { version = strings.ToLower(strings.TrimSpace(string(out))) } diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux.go b/vendor/github.com/shirou/gopsutil/host/host_linux.go index 14d09357d..b56cc98a2 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_linux.go +++ b/vendor/github.com/shirou/gopsutil/host/host_linux.go @@ -15,7 +15,7 @@ import ( "strings" "time" - "github.com/shirou/gopsutil/internal/common" + common "github.com/shirou/gopsutil/internal/common" ) type LSB struct { @@ -136,6 +136,26 @@ func Users() ([]UserStat, error) { } +func getOSRelease() (platform string, version string, err error) { + contents, err := common.ReadLines(common.HostEtc("os-release")) + if err != nil { + return "", "", nil // return empty + } + for _, line := range contents { + field := strings.Split(line, "=") + if len(field) < 2 { + continue + } + switch field[0] { + case "ID": // use ID for lowercase + platform = field[1] + case "VERSION": + version = field[1] + } + } + return platform, version, nil +} + func getLSB() (*LSB, error) { ret := &LSB{} if common.PathExists(common.HostEtc("lsb-release")) { @@ -164,7 +184,7 @@ func getLSB() (*LSB, error) { if err != nil { return ret, err } - out, err := exec.Command(lsb_release).Output() + out, err := invoke.Command(lsb_release) if err != nil { return ret, err } @@ -256,6 +276,18 @@ func PlatformInformation() (platform string, family string, version string, err } else if common.PathExists(common.HostEtc("arch-release")) { platform = "arch" version = lsb.Release + } else if common.PathExists(common.HostEtc("alpine-release")) { + platform = "alpine" + contents, err := common.ReadLines(common.HostEtc("alpine-release")) + if err == nil && len(contents) > 0 { + version = contents[0] + } + } else if common.PathExists(common.HostEtc("os-release")) { + p, v, err := getOSRelease() + if err == nil { + platform = p + version = v + } } else if lsb.ID == "RedHat" { platform = "redhat" version = lsb.Release @@ -290,6 +322,10 @@ func PlatformInformation() (platform string, family string, version string, err family = "arch" case "exherbo": family = "exherbo" + case "alpine": + family = "alpine" + case "coreos": + family = "coreos" } return platform, family, version, nil @@ -351,7 +387,7 @@ func Virtualization() (string, string, error) { if common.PathExists(filename + "/capabilities") { contents, err := common.ReadLines(filename + "/capabilities") if err == nil { - if common.StringsHas(contents, "control_d") { + if common.StringsContains(contents, "control_d") { role = "host" } } @@ -379,9 +415,9 @@ func Virtualization() (string, string, error) { if common.PathExists(filename) { contents, err := common.ReadLines(filename) if err == nil { - if common.StringsHas(contents, "QEMU Virtual CPU") || - common.StringsHas(contents, "Common KVM processor") || - common.StringsHas(contents, "Common 32-bit KVM processor") { + if common.StringsContains(contents, "QEMU Virtual CPU") || + common.StringsContains(contents, "Common KVM processor") || + common.StringsContains(contents, "Common 32-bit KVM processor") { system = "kvm" role = "guest" } @@ -402,8 +438,8 @@ func Virtualization() (string, string, error) { contents, err := common.ReadLines(filename + "/self/status") if err == nil { - if common.StringsHas(contents, "s_context:") || - common.StringsHas(contents, "VxID:") { + if common.StringsContains(contents, "s_context:") || + common.StringsContains(contents, "VxID:") { system = "linux-vserver" } // TODO: guest or host @@ -413,16 +449,28 @@ func Virtualization() (string, string, error) { if common.PathExists(filename + "/self/cgroup") { contents, err := common.ReadLines(filename + "/self/cgroup") if err == nil { - if common.StringsHas(contents, "lxc") || - common.StringsHas(contents, "docker") { + if common.StringsContains(contents, "lxc") { system = "lxc" role = "guest" - } else if common.PathExists("/usr/bin/lxc-version") { // TODO: which + } else if common.StringsContains(contents, "docker") { + system = "docker" + role = "guest" + } else if common.StringsContains(contents, "machine-rkt") { + system = "rkt" + role = "guest" + } else if common.PathExists("/usr/bin/lxc-version") { system = "lxc" role = "host" } } } + if common.PathExists(common.HostEtc("os-release")) { + p, _, err := getOSRelease() + if err == nil && p == "coreos" { + system = "rkt" // Is it true? + role = "host" + } + } return system, role, nil } diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go b/vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go index 37dbe5c8c..d081a0819 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go +++ b/vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go @@ -1,3 +1,5 @@ +// +build linux +// +build ppc64le // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/vendor/github.com/shirou/gopsutil/host/host_windows.go b/vendor/github.com/shirou/gopsutil/host/host_windows.go index 29f900c6e..18062dfe5 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_windows.go +++ b/vendor/github.com/shirou/gopsutil/host/host_windows.go @@ -50,7 +50,7 @@ func Info() (*InfoStat, error) { boot, err := BootTime() if err == nil { ret.BootTime = boot - ret.Uptime = uptime(boot) + ret.Uptime, _ = Uptime() } procs, err := process.Pids() @@ -76,7 +76,7 @@ func GetOSInfo() (Win32_OperatingSystem, error) { return dst[0], nil } -func BootTime() (uint64, error) { +func Uptime() (uint64, error) { if osInfo == nil { _, err := GetOSInfo() if err != nil { @@ -88,16 +88,16 @@ func BootTime() (uint64, error) { return uint64(now.Sub(t).Seconds()), nil } -func uptime(boot uint64) uint64 { - return uint64(time.Now().Unix()) - boot +func bootTime(up uint64) uint64 { + return uint64(time.Now().Unix()) - up } -func Uptime() (uint64, error) { - boot, err := BootTime() +func BootTime() (uint64, error) { + up, err := Uptime() if err != nil { return 0, err } - return uptime(boot), nil + return bootTime(up), nil } func PlatformInformation() (platform string, family string, version string, err error) { diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common.go b/vendor/github.com/shirou/gopsutil/internal/common/common.go index e190f4d13..42cbaf92a 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common.go @@ -8,8 +8,10 @@ package common // - windows (amd64) import ( "bufio" + "bytes" "errors" "io/ioutil" + "log" "net/url" "os" "os/exec" @@ -19,6 +21,12 @@ import ( "runtime" "strconv" "strings" + "time" +) + +var ( + Timeout = 3 * time.Second + TimeoutErr = errors.New("Command timed out.") ) type Invoker interface { @@ -28,7 +36,8 @@ type Invoker interface { type Invoke struct{} func (i Invoke) Command(name string, arg ...string) ([]byte, error) { - return exec.Command(name, arg...).Output() + cmd := exec.Command(name, arg...) + return CombinedOutputTimeout(cmd, Timeout) } type FakeInvoke struct { @@ -118,20 +127,20 @@ func IntToString(orig []int8) string { } func UintToString(orig []uint8) string { - ret := make([]byte, len(orig)) - size := -1 - for i, o := range orig { - if o == 0 { - size = i - break - } - ret[i] = byte(o) - } - if size == -1 { - size = len(orig) - } + ret := make([]byte, len(orig)) + size := -1 + for i, o := range orig { + if o == 0 { + size = i + break + } + ret[i] = byte(o) + } + if size == -1 { + size = len(orig) + } - return string(ret[0:size]) + return string(ret[0:size]) } func ByteToString(orig []byte) string { @@ -294,3 +303,41 @@ func HostSys(combineWith ...string) string { func HostEtc(combineWith ...string) string { return GetEnv("HOST_ETC", "/etc", combineWith...) } + +// CombinedOutputTimeout runs the given command with the given timeout and +// returns the combined output of stdout and stderr. +// If the command times out, it attempts to kill the process. +// copied from https://github.com/influxdata/telegraf +func CombinedOutputTimeout(c *exec.Cmd, timeout time.Duration) ([]byte, error) { + var b bytes.Buffer + c.Stdout = &b + c.Stderr = &b + if err := c.Start(); err != nil { + return nil, err + } + err := WaitTimeout(c, timeout) + return b.Bytes(), err +} + +// WaitTimeout waits for the given command to finish with a timeout. +// It assumes the command has already been started. +// If the command times out, it attempts to kill the process. +// copied from https://github.com/influxdata/telegraf +func WaitTimeout(c *exec.Cmd, timeout time.Duration) error { + timer := time.NewTimer(timeout) + done := make(chan error) + go func() { done <- c.Wait() }() + select { + case err := <-done: + timer.Stop() + return err + case <-timer.C: + if err := c.Process.Kill(); err != nil { + log.Printf("FATAL error killing process: %s", err) + return err + } + // wait for the command to return after killing it + <-done + return TimeoutErr + } +} diff --git a/vendor/github.com/shirou/gopsutil/mem/mem.go b/vendor/github.com/shirou/gopsutil/mem/mem.go index 5f122d11b..32558908a 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem.go @@ -2,8 +2,16 @@ package mem import ( "encoding/json" + + "github.com/shirou/gopsutil/internal/common" ) +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} +} + // Memory usage statistics. Total, Available and Used contain numbers of bytes // for human consumption. // diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go index 7094802d9..3eb33abb1 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go @@ -16,7 +16,7 @@ func getVMStat(vms *VirtualMemoryStat) error { if err != nil { return err } - out, err := exec.Command(vm_stat).Output() + out, err := invoke.Command(vm_stat) if err != nil { return err } diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go b/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go index 719405767..8cca44b53 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go @@ -93,7 +93,7 @@ func SwapMemory() (*SwapMemoryStat, error) { return nil, err } - out, err := exec.Command(swapinfo).Output() + out, err := invoke.Command(swapinfo) if err != nil { return nil, err } diff --git a/vendor/github.com/shirou/gopsutil/net/net.go b/vendor/github.com/shirou/gopsutil/net/net.go index 60f1069c8..4d120dc7e 100644 --- a/vendor/github.com/shirou/gopsutil/net/net.go +++ b/vendor/github.com/shirou/gopsutil/net/net.go @@ -18,15 +18,18 @@ func init() { } type IOCountersStat struct { - Name string `json:"name"` // interface name + Name string `json:"name"` // interface name BytesSent uint64 `json:"bytesSent"` // number of bytes sent BytesRecv uint64 `json:"bytesRecv"` // number of bytes received PacketsSent uint64 `json:"packetsSent"` // number of packets sent PacketsRecv uint64 `json:"packetsRecv"` // number of packets received - Errin uint64 `json:"errin"` // total number of errors while receiving - Errout uint64 `json:"errout"` // total number of errors while sending - Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped - Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD) + Errin uint64 `json:"errin"` // total number of errors while receiving + Errout uint64 `json:"errout"` // total number of errors while sending + Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped + Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD) + Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving + Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending + } // Addr is implemented compatibility to psutil diff --git a/vendor/github.com/shirou/gopsutil/net/net_darwin.go b/vendor/github.com/shirou/gopsutil/net/net_darwin.go index 4fa358a38..78ccb665d 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_darwin.go +++ b/vendor/github.com/shirou/gopsutil/net/net_darwin.go @@ -21,7 +21,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { if err != nil { return nil, err } - out, err := exec.Command(netstat, "-ibdnW").Output() + out, err := invoke.Command(netstat, "-ibdnW") if err != nil { return nil, err } diff --git a/vendor/github.com/shirou/gopsutil/net/net_freebsd.go b/vendor/github.com/shirou/gopsutil/net/net_freebsd.go index 3a67b4af4..2b546550e 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/net/net_freebsd.go @@ -16,7 +16,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { if err != nil { return nil, err } - out, err := exec.Command(netstat, "-ibdnW").Output() + out, err := invoke.Command(netstat, "-ibdnW") if err != nil { return nil, err } diff --git a/vendor/github.com/shirou/gopsutil/net/net_linux.go b/vendor/github.com/shirou/gopsutil/net/net_linux.go index e0247714f..0803d8e78 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_linux.go +++ b/vendor/github.com/shirou/gopsutil/net/net_linux.go @@ -63,6 +63,10 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { if err != nil { return ret, err } + fifoIn, err := strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return ret, err + } bytesSent, err := strconv.ParseUint(fields[8], 10, 64) if err != nil { return ret, err @@ -79,6 +83,10 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { if err != nil { return ret, err } + fifoOut, err := strconv.ParseUint(fields[14], 10, 64) + if err != nil { + return ret, err + } nic := IOCountersStat{ Name: interfaceName, @@ -86,10 +94,12 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { PacketsRecv: packetsRecv, Errin: errIn, Dropin: dropIn, + Fifoin: fifoIn, BytesSent: bytesSent, PacketsSent: packetsSent, Errout: errOut, Dropout: dropOut, + Fifoout: fifoOut, } ret = append(ret, nic) } diff --git a/vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go b/vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go new file mode 100644 index 000000000..529aeaa9a --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go @@ -0,0 +1,9 @@ +// +build linux +// +build arm64 + +package process + +const ( + ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK) + PageSize = 4096 // C.sysconf(C._SC_PAGE_SIZE) +) diff --git a/vendor/github.com/shirou/gopsutil/process/process_posix.go b/vendor/github.com/shirou/gopsutil/process/process_posix.go index 8853118ac..0751f6860 100644 --- a/vendor/github.com/shirou/gopsutil/process/process_posix.go +++ b/vendor/github.com/shirou/gopsutil/process/process_posix.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" "syscall" + + "github.com/shirou/gopsutil/internal/common" ) // POSIX @@ -72,7 +74,10 @@ func (p *Process) SendSignal(sig syscall.Signal) error { } cmd := exec.Command(kill, "-s", sigAsStr, strconv.Itoa(int(p.Pid))) cmd.Stderr = os.Stderr - err = cmd.Run() + if err := cmd.Start(); err != nil { + return err + } + err = common.WaitTimeout(cmd, common.Timeout) if err != nil { return err } diff --git a/vendor/github.com/shirou/gopsutil/process/process_windows.go b/vendor/github.com/shirou/gopsutil/process/process_windows.go index 3176cde05..c3d28376f 100644 --- a/vendor/github.com/shirou/gopsutil/process/process_windows.go +++ b/vendor/github.com/shirou/gopsutil/process/process_windows.go @@ -23,6 +23,11 @@ const ( MaxPathLength = 260 ) +var ( + modpsapi = syscall.NewLazyDLL("psapi.dll") + procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") +) + type SystemProcessInformation struct { NextEntryOffset uint64 NumberOfThreads uint64 @@ -46,13 +51,18 @@ type MemoryMapsStat struct { } type Win32_Process struct { - Name string - ExecutablePath *string - CommandLine *string - Priority uint32 - CreationDate *time.Time - ProcessID uint32 - ThreadCount uint32 + Name string + ExecutablePath *string + CommandLine *string + Priority uint32 + CreationDate *time.Time + ProcessID uint32 + ThreadCount uint32 + Status *string + ReadOperationCount uint64 + ReadTransferCount uint64 + WriteOperationCount uint64 + WriteTransferCount uint64 /* CSCreationClassName string @@ -76,14 +86,9 @@ type Win32_Process struct { PeakVirtualSize uint64 PeakWorkingSetSize uint32 PrivatePageCount uint64 - ReadOperationCount uint64 - ReadTransferCount uint64 - Status *string TerminationDate *time.Time UserModeTime uint64 WorkingSetSize uint64 - WriteOperationCount uint64 - WriteTransferCount uint64 */ } @@ -158,12 +163,12 @@ func (p *Process) CmdlineSlice() ([]string, error) { } func (p *Process) CreateTime() (int64, error) { - dst, err := GetWin32Proc(p.Pid) + ru, err := getRusage(p.Pid) if err != nil { return 0, fmt.Errorf("could not get CreationDate: %s", err) } - date := *dst[0].CreationDate - return date.Unix(), nil + + return ru.CreationTime.Nanoseconds() / 1000000, nil } func (p *Process) Cwd() (string, error) { @@ -207,8 +212,20 @@ func (p *Process) Rlimit() ([]RlimitStat, error) { return rlimit, common.ErrNotImplementedError } + func (p *Process) IOCounters() (*IOCountersStat, error) { - return nil, common.ErrNotImplementedError + dst, err := GetWin32Proc(p.Pid) + if err != nil || len(dst) == 0 { + return nil, fmt.Errorf("could not get Win32Proc: %s", err) + } + ret := &IOCountersStat{ + ReadCount: uint64(dst[0].ReadOperationCount), + ReadBytes: uint64(dst[0].ReadTransferCount), + WriteCount: uint64(dst[0].WriteOperationCount), + WriteBytes: uint64(dst[0].WriteTransferCount), + } + + return ret, nil } func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) { return nil, common.ErrNotImplementedError @@ -234,7 +251,17 @@ func (p *Process) CPUAffinity() ([]int32, error) { return nil, common.ErrNotImplementedError } func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { - return nil, common.ErrNotImplementedError + mem, err := getMemoryInfo(p.Pid) + if err != nil { + return nil, err + } + + ret := &MemoryInfoStat{ + RSS: mem.WorkingSetSize, + VMS: mem.PagefileUsage, + } + + return ret, nil } func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) { return nil, common.ErrNotImplementedError @@ -355,3 +382,45 @@ func getProcInfo(pid int32) (*SystemProcessInformation, error) { return &sysProcInfo, nil } + +func getRusage(pid int32) (*syscall.Rusage, error) { + var CPU syscall.Rusage + + c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) + if err != nil { + return nil, err + } + defer syscall.CloseHandle(c) + + if err := syscall.GetProcessTimes(c, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil { + return nil, err + } + + return &CPU, nil +} + +func getMemoryInfo(pid int32) (PROCESS_MEMORY_COUNTERS, error) { + var mem PROCESS_MEMORY_COUNTERS + c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) + if err != nil { + return mem, err + } + defer syscall.CloseHandle(c) + if err := getProcessMemoryInfo(c, &mem); err != nil { + return mem, err + } + + return mem, err +} + +func getProcessMemoryInfo(h syscall.Handle, mem *PROCESS_MEMORY_COUNTERS) (err error) { + r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(h), uintptr(unsafe.Pointer(mem)), uintptr(unsafe.Sizeof(*mem))) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} diff --git a/vendor/github.com/shirou/gopsutil/process/process_windows_386.go b/vendor/github.com/shirou/gopsutil/process/process_windows_386.go new file mode 100644 index 000000000..68f3153dc --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_windows_386.go @@ -0,0 +1,16 @@ +// +build windows + +package process + +type PROCESS_MEMORY_COUNTERS struct { + CB uint32 + PageFaultCount uint32 + PeakWorkingSetSize uint32 + WorkingSetSize uint32 + QuotaPeakPagedPoolUsage uint32 + QuotaPagedPoolUsage uint32 + QuotaPeakNonPagedPoolUsage uint32 + QuotaNonPagedPoolUsage uint32 + PagefileUsage uint32 + PeakPagefileUsage uint32 +} diff --git a/vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go b/vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go new file mode 100644 index 000000000..df286dfff --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go @@ -0,0 +1,16 @@ +// +build windows + +package process + +type PROCESS_MEMORY_COUNTERS struct { + CB uint32 + PageFaultCount uint32 + PeakWorkingSetSize uint64 + WorkingSetSize uint64 + QuotaPeakPagedPoolUsage uint64 + QuotaPagedPoolUsage uint64 + QuotaPeakNonPagedPoolUsage uint64 + QuotaNonPagedPoolUsage uint64 + PagefileUsage uint64 + PeakPagefileUsage uint64 +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 2332de440..0cbebc659 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -666,52 +666,52 @@ "revision": "983d3a5fab1bf04d1b412465d2d9f8430e2e917e" }, { - "checksumSHA1": "dtcffK/n1nDKPtvHg2GnU1C194s=", + "checksumSHA1": "G1oy2AGv5pCnNL0hRfg+mlX4Uq4=", "comment": "1.0.0-230-gf58654f", "path": "github.com/shirou/gopsutil/cpu", - "revision": "7b991b8135166c7fc81b65665a2f35c7a1966cfc", - "revisionTime": "2016-05-04T15:08:50Z" + "revision": "5c1bfed85550640833e8bbf50156d114ba99fbf2", + "revisionTime": "2016-06-17T08:26:08Z" }, { - "checksumSHA1": "zs7XTdxVVhxUUwA4kSdSJlNfVZc=", + "checksumSHA1": "x4HZyWURx/UwxHVrdaTGbTFd198=", "path": "github.com/shirou/gopsutil/disk", - "revision": "83c6e72cbdef6e8ada934549abf700ff0ba96776", - "revisionTime": "2016-05-20T22:39:10Z" + "revision": "5c1bfed85550640833e8bbf50156d114ba99fbf2", + "revisionTime": "2016-06-17T08:26:08Z" }, { - "checksumSHA1": "lpPewrgMOYaTKZ0wRZpmZJxnEBw=", + "checksumSHA1": "tV0skuyoy255WiTlKjd24T+5DeU=", "comment": "1.0.0-230-gf58654f", "path": "github.com/shirou/gopsutil/host", - "revision": "7b991b8135166c7fc81b65665a2f35c7a1966cfc", - "revisionTime": "2016-05-04T15:08:50Z" + "revision": "5c1bfed85550640833e8bbf50156d114ba99fbf2", + "revisionTime": "2016-06-17T08:26:08Z" }, { - "checksumSHA1": "xrMuUxCr8UckY5oI2lwCerYwIhk=", + "checksumSHA1": "zJZyxS96XiEnDJSZkWwXtktziRY=", "comment": "1.0.0-230-gf58654f", "path": "github.com/shirou/gopsutil/internal/common", - "revision": "7b991b8135166c7fc81b65665a2f35c7a1966cfc", - "revisionTime": "2016-05-04T15:08:50Z" + "revision": "5c1bfed85550640833e8bbf50156d114ba99fbf2", + "revisionTime": "2016-06-17T08:26:08Z" }, { - "checksumSHA1": "bHTDi2QAN4SmdZpHOtyQ6fQeCnQ=", + "checksumSHA1": "LUipApIqOLcKbZfwXknNCifGles=", "comment": "1.0.0-230-gf58654f", "path": "github.com/shirou/gopsutil/mem", - "revision": "7b991b8135166c7fc81b65665a2f35c7a1966cfc", - "revisionTime": "2016-05-04T15:08:50Z" + "revision": "5c1bfed85550640833e8bbf50156d114ba99fbf2", + "revisionTime": "2016-06-17T08:26:08Z" }, { - "checksumSHA1": "LHJDMUXWamoP/yje0R42k96OPG8=", + "checksumSHA1": "k57srhFXKSysrFdEh3b6oiO48hw=", "comment": "1.0.0-230-gf58654f", "path": "github.com/shirou/gopsutil/net", - "revision": "7b991b8135166c7fc81b65665a2f35c7a1966cfc", - "revisionTime": "2016-05-04T15:08:50Z" + "revision": "5c1bfed85550640833e8bbf50156d114ba99fbf2", + "revisionTime": "2016-06-17T08:26:08Z" }, { - "checksumSHA1": "o544bXejDPLi6qpjHav8a91W4Ks=", + "checksumSHA1": "+m5V0QobB9gklJkz+zk0NvaSeOs=", "comment": "1.0.0-230-gf58654f", "path": "github.com/shirou/gopsutil/process", - "revision": "7b991b8135166c7fc81b65665a2f35c7a1966cfc", - "revisionTime": "2016-05-04T15:08:50Z" + "revision": "5c1bfed85550640833e8bbf50156d114ba99fbf2", + "revisionTime": "2016-06-17T08:26:08Z" }, { "path": "github.com/shirou/w32", From f9562cf656b94ed787ee7903219d0342fbb4eca3 Mon Sep 17 00:00:00 2001 From: Sean Chittenden Date: Fri, 17 Jun 2016 10:19:59 -0700 Subject: [PATCH 2/3] Lump this fix in with gopsutils: guard against errors from stats. --- command/alloc_status.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/command/alloc_status.go b/command/alloc_status.go index 0c4d76af6..80d816d16 100644 --- a/command/alloc_status.go +++ b/command/alloc_status.go @@ -133,6 +133,10 @@ func (c *AllocStatusCommand) Run(args []string) int { var statsErr error var stats *api.AllocResourceUsage stats, statsErr = client.Allocations().Stats(alloc, nil) + if statsErr != nil { + c.Ui.Output("") + c.Ui.Error(fmt.Sprintf("couldn't retreive stats: %v", statsErr)) + } // Format the allocation data basic := []string{ @@ -166,11 +170,6 @@ func (c *AllocStatusCommand) Run(args []string) int { c.Ui.Output(formatAllocMetrics(alloc.Metrics, true, " ")) } - if statsErr != nil { - c.Ui.Output("") - c.Ui.Error(fmt.Sprintf("couldn't retreive stats: %v", statsErr)) - } - return 0 } From 7566e8a04bb76c6dadc41f45767c69109d3003e9 Mon Sep 17 00:00:00 2001 From: Sean Chittenden Date: Fri, 17 Jun 2016 12:22:17 -0700 Subject: [PATCH 3/3] Improve the error messages when obtaining node and alloc stats --- command/alloc_status.go | 2 +- command/node_status.go | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/command/alloc_status.go b/command/alloc_status.go index 80d816d16..9b88c30b4 100644 --- a/command/alloc_status.go +++ b/command/alloc_status.go @@ -135,7 +135,7 @@ func (c *AllocStatusCommand) Run(args []string) int { stats, statsErr = client.Allocations().Stats(alloc, nil) if statsErr != nil { c.Ui.Output("") - c.Ui.Error(fmt.Sprintf("couldn't retreive stats: %v", statsErr)) + c.Ui.Error(fmt.Sprintf("couldn't retrieve stats (HINT: ensure Client.Advertise.HTTP is set): %v", statsErr)) } // Format the allocation data diff --git a/command/node_status.go b/command/node_status.go index 9b38d580e..1796c36fc 100644 --- a/command/node_status.go +++ b/command/node_status.go @@ -222,6 +222,10 @@ func (c *NodeStatusCommand) Run(args []string) int { func (c *NodeStatusCommand) formatNode(client *api.Client, node *api.Node) int { // Get the host stats hostStats, nodeStatsErr := client.Nodes().Stats(node.ID, nil) + if nodeStatsErr != nil { + c.Ui.Output("") + c.Ui.Error(fmt.Sprintf("error fetching node stats (HINT: ensure Client.Advertise.HTTP is set): %v", nodeStatsErr)) + } // Format the header output basic := []string{ @@ -257,6 +261,10 @@ func (c *NodeStatusCommand) formatNode(client *api.Client, node *api.Node) int { } hostResources, err := getHostResources(hostStats, node) + if err != nil { + c.Ui.Output("") + c.Ui.Error(fmt.Sprintf("error fetching node stats (HINT: ensure Client.Advertise.HTTP is set): %v", err)) + } if err == nil { c.Ui.Output(c.Colorize().Color("\n[bold]Host Resource Utilization[reset]")) c.Ui.Output(formatList(hostResources)) @@ -286,10 +294,6 @@ func (c *NodeStatusCommand) formatNode(client *api.Client, node *api.Node) int { if c.verbose { c.formatAttributes(node) } - if nodeStatsErr != nil { - c.Ui.Output("") - c.Ui.Error(fmt.Sprintf("error fetching node stats: %v", nodeStatsErr)) - } return 0 }