Merge pull request #177 from shirou/v2

change to version2 with many of incompatiblity.
tags/v2.0.0^0 v2.0.0
shirou 9 years ago
commit e8f7a95747

@ -0,0 +1,18 @@
.PHONY: help check
.DEFAULT_GOAL := help
SUBPKGS=cpu disk docker host internal load mem net process
help: ## Show help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
check: ## Check
errcheck -ignore="Close|Run|Write" ./...
golint ./... | egrep -v 'underscores|HttpOnly|should have comment|comment on exported|CamelCase|VM|UID'
build_test: ## test only buildable
GOOS=linux go test ./... | grep -v "exec format error"
GOOS=freebsd go test ./... | grep -v "exec format error"
CGO_ENABLED=0 GOOS=darwin go test ./... | grep -v "exec format error"
CGO_ENABLED=1 GOOS=darwin go test ./... | grep -v "exec format error"
GOOS=windows go test ./...| grep -v "exec format error"

@ -14,9 +14,15 @@ This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is por
psutil functions on some architectures... psutil functions on some architectures...
.. highlights:: Breaking Changes will comes! .. highlights:: Breaking Changes!
We introduced versioning by using gopkgin. And breaking changes will be introduced at v2. See `issue 174 <https://github.com/shirou/gopsutil/issues/174>`_ . Breaking changes is introduced at v2. See `issue 174 <https://github.com/shirou/gopsutil/issues/174>`_ .
Migrating to v2
-------------------------
On gopsutil itself, `v2migration.sh <https://github.com/shirou/gopsutil/blob/v2/v2migration.sh>`_ is used for migration. It can not be commly used, but it may help to your migration.
Available Architectures Available Architectures
@ -33,24 +39,26 @@ All works are implemented without cgo by porting c struct to golang struct.
Usage Usage
--------- ---------
Note: gopsutil.v2 breaks compatibility. If you want to stay with compatibility, please use `gopkg.in/shirou/gopsutil.v1`. Note: gopsutil v2 breaks compatibility. If you want to stay with compatibility, please use v1 branch and vendoring.
.. code:: go .. code:: go
package main
import ( import (
"fmt" "fmt"
mem "gopkg.in/shirou/gopsutil.v2/mem" "github.com/shirou/gopsutil/mem"
) )
func main() { func main() {
v, _ := mem.VirtualMemory() v, _ := mem.VirtualMemory()
// almost every return value is a struct // almost every return value is a struct
fmt.Printf("Total: %v, Free:%v, UsedPercent:%f%%\n", v.Total, v.Free, v.UsedPercent) fmt.Printf("Total: %v, Free:%v, UsedPercent:%f%%\n", v.Total, v.Free, v.UsedPercent)
// convert to JSON. String() is also implemented // convert to JSON. String() is also implemented
fmt.Println(v) fmt.Println(v)
} }
The output is below. The output is below.
@ -58,7 +66,7 @@ The output is below.
:: ::
Total: 3179569152, Free:284233728, UsedPercent:84.508194% Total: 3179569152, Free:284233728, UsedPercent:84.508194%
{"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip)} {"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip...)}
You can set an alternative location to /proc by setting the HOST_PROC environment variable. You can set an alternative location to /proc by setting the HOST_PROC environment variable.
You can set an alternative location to /sys by setting the HOST_SYS environment variable. You can set an alternative location to /sys by setting the HOST_SYS environment variable.

@ -7,7 +7,7 @@ import (
"strings" "strings"
) )
type CPUTimesStat struct { type TimesStat struct {
CPU string `json:"cpu"` CPU string `json:"cpu"`
User float64 `json:"user"` User float64 `json:"user"`
System float64 `json:"system"` System float64 `json:"system"`
@ -18,33 +18,33 @@ type CPUTimesStat struct {
Softirq float64 `json:"softirq"` Softirq float64 `json:"softirq"`
Steal float64 `json:"steal"` Steal float64 `json:"steal"`
Guest float64 `json:"guest"` Guest float64 `json:"guest"`
GuestNice float64 `json:"guest_nice"` GuestNice float64 `json:"guestNice"`
Stolen float64 `json:"stolen"` Stolen float64 `json:"stolen"`
} }
type CPUInfoStat struct { type InfoStat struct {
CPU int32 `json:"cpu"` CPU int32 `json:"cpu"`
VendorID string `json:"vendor_id"` VendorID string `json:"vendorId"`
Family string `json:"family"` Family string `json:"family"`
Model string `json:"model"` Model string `json:"model"`
Stepping int32 `json:"stepping"` Stepping int32 `json:"stepping"`
PhysicalID string `json:"physical_id"` PhysicalID string `json:"physicalId"`
CoreID string `json:"core_id"` CoreID string `json:"coreId"`
Cores int32 `json:"cores"` Cores int32 `json:"cores"`
ModelName string `json:"model_name"` ModelName string `json:"modelName"`
Mhz float64 `json:"mhz"` Mhz float64 `json:"mhz"`
CacheSize int32 `json:"cache_size"` CacheSize int32 `json:"cacheSize"`
Flags []string `json:"flags"` Flags []string `json:"flags"`
} }
var lastCPUTimes []CPUTimesStat var lastCPUTimes []TimesStat
var lastPerCPUTimes []CPUTimesStat var lastPerCPUTimes []TimesStat
func CPUCounts(logical bool) (int, error) { func Counts(logical bool) (int, error) {
return runtime.NumCPU(), nil return runtime.NumCPU(), nil
} }
func (c CPUTimesStat) String() string { func (c TimesStat) String() string {
v := []string{ v := []string{
`"cpu":"` + c.CPU + `"`, `"cpu":"` + c.CPU + `"`,
`"user":` + strconv.FormatFloat(c.User, 'f', 1, 64), `"user":` + strconv.FormatFloat(c.User, 'f', 1, 64),
@ -56,7 +56,7 @@ func (c CPUTimesStat) String() string {
`"softirq":` + strconv.FormatFloat(c.Softirq, 'f', 1, 64), `"softirq":` + strconv.FormatFloat(c.Softirq, 'f', 1, 64),
`"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64), `"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64),
`"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64), `"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64),
`"guest_nice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64), `"guestNice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64),
`"stolen":` + strconv.FormatFloat(c.Stolen, 'f', 1, 64), `"stolen":` + strconv.FormatFloat(c.Stolen, 'f', 1, 64),
} }
@ -64,13 +64,13 @@ func (c CPUTimesStat) String() string {
} }
// Total returns the total number of seconds in a CPUTimesStat // Total returns the total number of seconds in a CPUTimesStat
func (c CPUTimesStat) Total() float64 { func (c TimesStat) Total() float64 {
total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + c.Steal + total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + c.Steal +
c.Guest + c.GuestNice + c.Idle + c.Stolen c.Guest + c.GuestNice + c.Idle + c.Stolen
return total return total
} }
func (c CPUInfoStat) String() string { func (c InfoStat) String() string {
s, _ := json.Marshal(c) s, _ := json.Marshal(c)
return string(s) return string(s)
} }

@ -21,7 +21,7 @@ const (
// default value. from time.h // default value. from time.h
var ClocksPerSec = float64(128) var ClocksPerSec = float64(128)
func CPUTimes(percpu bool) ([]CPUTimesStat, error) { func Times(percpu bool) ([]TimesStat, error) {
if percpu { if percpu {
return perCPUTimes() return perCPUTimes()
} }
@ -30,15 +30,18 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
} }
// Returns only one CPUInfoStat on FreeBSD // Returns only one CPUInfoStat on FreeBSD
func CPUInfo() ([]CPUInfoStat, error) { func Info() ([]InfoStat, error) {
var ret []CPUInfoStat var ret []InfoStat
sysctl, err := exec.LookPath("/usr/sbin/sysctl")
out, err := exec.Command("/usr/sbin/sysctl", "machdep.cpu").Output() if err != nil {
return ret, err
}
out, err := exec.Command(sysctl, "machdep.cpu").Output()
if err != nil { if err != nil {
return ret, err return ret, err
} }
c := CPUInfoStat{} c := InfoStat{}
for _, line := range strings.Split(string(out), "\n") { for _, line := range strings.Split(string(out), "\n") {
values := strings.Fields(line) values := strings.Fields(line)
if len(values) < 1 { if len(values) < 1 {
@ -87,7 +90,7 @@ func CPUInfo() ([]CPUInfoStat, error) {
// Use the rated frequency of the CPU. This is a static value and does not // Use the rated frequency of the CPU. This is a static value and does not
// account for low power or Turbo Boost modes. // account for low power or Turbo Boost modes.
out, err = exec.Command("/usr/sbin/sysctl", "hw.cpufrequency").Output() out, err = exec.Command(sysctl, "hw.cpufrequency").Output()
if err != nil { if err != nil {
return ret, err return ret, err
} }

@ -25,7 +25,7 @@ import (
// these CPU times for darwin is borrowed from influxdb/telegraf. // these CPU times for darwin is borrowed from influxdb/telegraf.
func perCPUTimes() ([]CPUTimesStat, error) { func perCPUTimes() ([]TimesStat, error) {
var ( var (
count C.mach_msg_type_number_t count C.mach_msg_type_number_t
cpuload *C.processor_cpu_load_info_data_t cpuload *C.processor_cpu_load_info_data_t
@ -59,7 +59,7 @@ func perCPUTimes() ([]CPUTimesStat, error) {
bbuf := bytes.NewBuffer(buf) bbuf := bytes.NewBuffer(buf)
var ret []CPUTimesStat var ret []TimesStat
for i := 0; i < int(ncpu); i++ { for i := 0; i < int(ncpu); i++ {
err := binary.Read(bbuf, binary.LittleEndian, &cpu_ticks) err := binary.Read(bbuf, binary.LittleEndian, &cpu_ticks)
@ -67,7 +67,7 @@ func perCPUTimes() ([]CPUTimesStat, error) {
return nil, err return nil, err
} }
c := CPUTimesStat{ c := TimesStat{
CPU: fmt.Sprintf("cpu%d", i), CPU: fmt.Sprintf("cpu%d", i),
User: float64(cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec, User: float64(cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec, System: float64(cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
@ -81,7 +81,7 @@ func perCPUTimes() ([]CPUTimesStat, error) {
return ret, nil return ret, nil
} }
func allCPUTimes() ([]CPUTimesStat, error) { func allCPUTimes() ([]TimesStat, error) {
var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT
var cpuload C.host_cpu_load_info_data_t var cpuload C.host_cpu_load_info_data_t
@ -94,7 +94,7 @@ func allCPUTimes() ([]CPUTimesStat, error) {
return nil, fmt.Errorf("host_statistics error=%d", status) return nil, fmt.Errorf("host_statistics error=%d", status)
} }
c := CPUTimesStat{ c := TimesStat{
CPU: "cpu-total", CPU: "cpu-total",
User: float64(cpuload.cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec, User: float64(cpuload.cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec, System: float64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
@ -102,6 +102,6 @@ func allCPUTimes() ([]CPUTimesStat, error) {
Idle: float64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec, Idle: float64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
} }
return []CPUTimesStat{c}, nil return []TimesStat{c}, nil
} }

@ -5,10 +5,10 @@ package cpu
import "github.com/shirou/gopsutil/internal/common" import "github.com/shirou/gopsutil/internal/common"
func perCPUTimes() ([]CPUTimesStat, error) { func perCPUTimes() ([]TimesStat, error) {
return []CPUTimesStat{}, common.NotImplementedError return []TimesStat{}, common.ErrNotImplementedError
} }
func allCPUTimes() ([]CPUTimesStat, error) { func allCPUTimes() ([]TimesStat, error) {
return []CPUTimesStat{}, common.NotImplementedError return []TimesStat{}, common.ErrNotImplementedError
} }

@ -25,7 +25,11 @@ const (
var ClocksPerSec = float64(128) var ClocksPerSec = float64(128)
func init() { func init() {
out, err := exec.Command("/usr/bin/getconf", "CLK_TCK").Output() getconf, err := exec.LookPath("/usr/bin/getconf")
if err != nil {
return
}
out, err := exec.Command(getconf, "CLK_TCK").Output()
// ignore errors // ignore errors
if err == nil { if err == nil {
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
@ -35,14 +39,14 @@ func init() {
} }
} }
func CPUTimes(percpu bool) ([]CPUTimesStat, error) { func Times(percpu bool) ([]TimesStat, error) {
var ret []CPUTimesStat var ret []TimesStat
var sysctlCall string var sysctlCall string
var ncpu int var ncpu int
if percpu { if percpu {
sysctlCall = "kern.cp_times" sysctlCall = "kern.cp_times"
ncpu, _ = CPUCounts(true) ncpu, _ = Counts(true)
} else { } else {
sysctlCall = "kern.cp_time" sysctlCall = "kern.cp_time"
ncpu = 1 ncpu = 1
@ -76,7 +80,7 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
return ret, err return ret, err
} }
c := CPUTimesStat{ c := TimesStat{
User: float64(user / ClocksPerSec), User: float64(user / ClocksPerSec),
Nice: float64(nice / ClocksPerSec), Nice: float64(nice / ClocksPerSec),
System: float64(sys / ClocksPerSec), System: float64(sys / ClocksPerSec),
@ -96,13 +100,13 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
} }
// Returns only one CPUInfoStat on FreeBSD // Returns only one CPUInfoStat on FreeBSD
func CPUInfo() ([]CPUInfoStat, error) { func Info() ([]InfoStat, error) {
filename := "/var/run/dmesg.boot" filename := "/var/run/dmesg.boot"
lines, _ := common.ReadLines(filename) lines, _ := common.ReadLines(filename)
var ret []CPUInfoStat var ret []InfoStat
c := CPUInfoStat{} c := InfoStat{}
for _, line := range lines { for _, line := range lines {
if matches := regexp.MustCompile(`CPU:\s+(.+) \(([\d.]+).+\)`).FindStringSubmatch(line); matches != nil { if matches := regexp.MustCompile(`CPU:\s+(.+) \(([\d.]+).+\)`).FindStringSubmatch(line); matches != nil {
c.ModelName = matches[1] c.ModelName = matches[1]

@ -15,7 +15,11 @@ import (
var cpu_tick = float64(100) var cpu_tick = float64(100)
func init() { func init() {
out, err := exec.Command("/usr/bin/getconf", "CLK_TCK").Output() getconf, err := exec.LookPath("/usr/bin/getconf")
if err != nil {
return
}
out, err := exec.Command(getconf, "CLK_TCK").Output()
// ignore errors // ignore errors
if err == nil { if err == nil {
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
@ -25,7 +29,7 @@ func init() {
} }
} }
func CPUTimes(percpu bool) ([]CPUTimesStat, error) { func Times(percpu bool) ([]TimesStat, error) {
filename := common.HostProc("stat") filename := common.HostProc("stat")
var lines = []string{} var lines = []string{}
if percpu { if percpu {
@ -37,13 +41,13 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
break break
} }
lines = append(lines, line) lines = append(lines, line)
startIdx += 1 startIdx++
} }
} else { } else {
lines, _ = common.ReadLinesOffsetN(filename, 0, 1) lines, _ = common.ReadLinesOffsetN(filename, 0, 1)
} }
ret := make([]CPUTimesStat, 0, len(lines)) ret := make([]TimesStat, 0, len(lines))
for _, line := range lines { for _, line := range lines {
ct, err := parseStatLine(line) ct, err := parseStatLine(line)
@ -56,13 +60,13 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
return ret, nil return ret, nil
} }
func sysCpuPath(cpu int32, relPath string) string { func sysCPUPath(cpu int32, relPath string) string {
return common.HostSys(fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath) return common.HostSys(fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath)
} }
func finishCPUInfo(c *CPUInfoStat) error { func finishCPUInfo(c *InfoStat) error {
if c.Mhz == 0 { if c.Mhz == 0 {
lines, err := common.ReadLines(sysCpuPath(c.CPU, "cpufreq/cpuinfo_max_freq")) lines, err := common.ReadLines(sysCPUPath(c.CPU, "cpufreq/cpuinfo_max_freq"))
if err == nil { if err == nil {
value, err := strconv.ParseFloat(lines[0], 64) value, err := strconv.ParseFloat(lines[0], 64)
if err != nil { if err != nil {
@ -72,7 +76,7 @@ func finishCPUInfo(c *CPUInfoStat) error {
} }
} }
if len(c.CoreID) == 0 { if len(c.CoreID) == 0 {
lines, err := common.ReadLines(sysCpuPath(c.CPU, "topology/core_id")) lines, err := common.ReadLines(sysCPUPath(c.CPU, "topology/coreId"))
if err == nil { if err == nil {
c.CoreID = lines[0] c.CoreID = lines[0]
} }
@ -87,13 +91,13 @@ func finishCPUInfo(c *CPUInfoStat) error {
// Sockets often come with many physical CPU cores. // Sockets often come with many physical CPU cores.
// For example a single socket board with two cores each with HT will // For example a single socket board with two cores each with HT will
// return 4 CPUInfoStat structs on Linux and the "Cores" field set to 1. // return 4 CPUInfoStat structs on Linux and the "Cores" field set to 1.
func CPUInfo() ([]CPUInfoStat, error) { func Info() ([]InfoStat, error) {
filename := common.HostProc("cpuinfo") filename := common.HostProc("cpuinfo")
lines, _ := common.ReadLines(filename) lines, _ := common.ReadLines(filename)
var ret []CPUInfoStat var ret []InfoStat
c := CPUInfoStat{CPU: -1, Cores: 1} c := InfoStat{CPU: -1, Cores: 1}
for _, line := range lines { for _, line := range lines {
fields := strings.Split(line, ":") fields := strings.Split(line, ":")
if len(fields) < 2 { if len(fields) < 2 {
@ -111,13 +115,13 @@ func CPUInfo() ([]CPUInfoStat, error) {
} }
ret = append(ret, c) ret = append(ret, c)
} }
c = CPUInfoStat{Cores: 1} c = InfoStat{Cores: 1}
t, err := strconv.ParseInt(value, 10, 64) t, err := strconv.ParseInt(value, 10, 64)
if err != nil { if err != nil {
return ret, err return ret, err
} }
c.CPU = int32(t) c.CPU = int32(t)
case "vendor_id": case "vendorId":
c.VendorID = value c.VendorID = value
case "cpu family": case "cpu family":
c.Family = value c.Family = value
@ -163,7 +167,7 @@ func CPUInfo() ([]CPUInfoStat, error) {
return ret, nil return ret, nil
} }
func parseStatLine(line string) (*CPUTimesStat, error) { func parseStatLine(line string) (*TimesStat, error) {
fields := strings.Fields(line) fields := strings.Fields(line)
if strings.HasPrefix(fields[0], "cpu") == false { if strings.HasPrefix(fields[0], "cpu") == false {
@ -204,7 +208,7 @@ func parseStatLine(line string) (*CPUTimesStat, error) {
return nil, err return nil, err
} }
ct := &CPUTimesStat{ ct := &TimesStat{
CPU: cpu, CPU: cpu,
User: float64(user) / cpu_tick, User: float64(user) / cpu_tick,
Nice: float64(nice) / cpu_tick, Nice: float64(nice) / cpu_tick,

@ -9,14 +9,14 @@ import (
) )
func TestCpu_times(t *testing.T) { func TestCpu_times(t *testing.T) {
v, err := CPUTimes(false) v, err := Times(false)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
if len(v) == 0 { if len(v) == 0 {
t.Error("could not get CPUs ", err) t.Error("could not get CPUs ", err)
} }
empty := CPUTimesStat{} empty := TimesStat{}
for _, vv := range v { for _, vv := range v {
if vv == empty { if vv == empty {
t.Errorf("could not get CPU User: %v", vv) t.Errorf("could not get CPU User: %v", vv)
@ -25,7 +25,7 @@ func TestCpu_times(t *testing.T) {
} }
func TestCpu_counts(t *testing.T) { func TestCpu_counts(t *testing.T) {
v, err := CPUCounts(true) v, err := Counts(true)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
@ -35,20 +35,20 @@ func TestCpu_counts(t *testing.T) {
} }
func TestCPUTimeStat_String(t *testing.T) { func TestCPUTimeStat_String(t *testing.T) {
v := CPUTimesStat{ v := TimesStat{
CPU: "cpu0", CPU: "cpu0",
User: 100.1, User: 100.1,
System: 200.1, System: 200.1,
Idle: 300.1, Idle: 300.1,
} }
e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guest_nice":0.0,"stolen":0.0}` e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0,"stolen":0.0}`
if e != fmt.Sprintf("%v", v) { if e != fmt.Sprintf("%v", v) {
t.Errorf("CPUTimesStat string is invalid: %v", v) t.Errorf("CPUTimesStat string is invalid: %v", v)
} }
} }
func TestCpuInfo(t *testing.T) { func TestCpuInfo(t *testing.T) {
v, err := CPUInfo() v, err := Info()
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
@ -68,7 +68,7 @@ func testCPUPercent(t *testing.T, percpu bool) {
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
testCount = 100 testCount = 100
v, err := CPUPercent(time.Millisecond, percpu) v, err := Percent(time.Millisecond, percpu)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
@ -81,7 +81,7 @@ func testCPUPercent(t *testing.T, percpu bool) {
} }
for i := 0; i < testCount; i++ { for i := 0; i < testCount; i++ {
duration := time.Duration(10) * time.Microsecond duration := time.Duration(10) * time.Microsecond
v, err := CPUPercent(duration, percpu) v, err := Percent(duration, percpu)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }

@ -7,14 +7,14 @@ import (
"time" "time"
) )
func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) { func Percent(interval time.Duration, percpu bool) ([]float64, error) {
getAllBusy := func(t CPUTimesStat) (float64, float64) { getAllBusy := func(t TimesStat) (float64, float64) {
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen
return busy + t.Idle, busy return busy + t.Idle, busy
} }
calculate := func(t1, t2 CPUTimesStat) float64 { calculate := func(t1, t2 TimesStat) float64 {
t1All, t1Busy := getAllBusy(t1) t1All, t1Busy := getAllBusy(t1)
t2All, t2Busy := getAllBusy(t2) t2All, t2Busy := getAllBusy(t2)
@ -28,7 +28,7 @@ func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) {
} }
// Get CPU usage at the start of the interval. // Get CPU usage at the start of the interval.
cpuTimes1, err := CPUTimes(percpu) cpuTimes1, err := Times(percpu)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -38,7 +38,7 @@ func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) {
} }
// And at the end of the interval. // And at the end of the interval.
cpuTimes2, err := CPUTimes(percpu) cpuTimes2, err := Times(percpu)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -19,14 +19,14 @@ type Win32_Processor struct {
Manufacturer string Manufacturer string
Name string Name string
NumberOfLogicalProcessors uint32 NumberOfLogicalProcessors uint32
ProcessorId *string ProcessorID *string
Stepping *string Stepping *string
MaxClockSpeed uint32 MaxClockSpeed uint32
} }
// TODO: Get percpu // TODO: Get percpu
func CPUTimes(percpu bool) ([]CPUTimesStat, error) { func Times(percpu bool) ([]TimesStat, error) {
var ret []CPUTimesStat var ret []TimesStat
var lpIdleTime common.FILETIME var lpIdleTime common.FILETIME
var lpKernelTime common.FILETIME var lpKernelTime common.FILETIME
@ -46,7 +46,7 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
kernel := ((HIT * float64(lpKernelTime.DwHighDateTime)) + (LOT * float64(lpKernelTime.DwLowDateTime))) kernel := ((HIT * float64(lpKernelTime.DwHighDateTime)) + (LOT * float64(lpKernelTime.DwLowDateTime)))
system := (kernel - idle) system := (kernel - idle)
ret = append(ret, CPUTimesStat{ ret = append(ret, TimesStat{
Idle: float64(idle), Idle: float64(idle),
User: float64(user), User: float64(user),
System: float64(system), System: float64(system),
@ -54,8 +54,8 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
return ret, nil return ret, nil
} }
func CPUInfo() ([]CPUInfoStat, error) { func Info() ([]InfoStat, error) {
var ret []CPUInfoStat var ret []InfoStat
var dst []Win32_Processor var dst []Win32_Processor
q := wmi.CreateQuery(&dst, "") q := wmi.CreateQuery(&dst, "")
err := wmi.Query(q, &dst) err := wmi.Query(q, &dst)
@ -66,11 +66,11 @@ func CPUInfo() ([]CPUInfoStat, error) {
var procID string var procID string
for i, l := range dst { for i, l := range dst {
procID = "" procID = ""
if l.ProcessorId != nil { if l.ProcessorID != nil {
procID = *l.ProcessorId procID = *l.ProcessorID
} }
cpu := CPUInfoStat{ cpu := InfoStat{
CPU: int32(i), CPU: int32(i),
Family: fmt.Sprintf("%d", l.Family), Family: fmt.Sprintf("%d", l.Family),
VendorID: l.Manufacturer, VendorID: l.Manufacturer,
@ -86,7 +86,7 @@ func CPUInfo() ([]CPUInfoStat, error) {
return ret, nil return ret, nil
} }
func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) { func Percent(interval time.Duration, percpu bool) ([]float64, error) {
var ret []float64 var ret []float64
var dst []Win32_Processor var dst []Win32_Processor
q := wmi.CreateQuery(&dst, "") q := wmi.CreateQuery(&dst, "")

@ -4,49 +4,49 @@ import (
"encoding/json" "encoding/json"
) )
type DiskUsageStat struct { type UsageStat struct {
Path string `json:"path"` Path string `json:"path"`
Fstype string `json:"fstype"` Fstype string `json:"fstype"`
Total uint64 `json:"total"` Total uint64 `json:"total"`
Free uint64 `json:"free"` Free uint64 `json:"free"`
Used uint64 `json:"used"` Used uint64 `json:"used"`
UsedPercent float64 `json:"used_percent"` UsedPercent float64 `json:"usedPercent"`
InodesTotal uint64 `json:"inodes_total"` InodesTotal uint64 `json:"inodesTotal"`
InodesUsed uint64 `json:"inodes_used"` InodesUsed uint64 `json:"inodesUsed"`
InodesFree uint64 `json:"inodes_free"` InodesFree uint64 `json:"inodesFree"`
InodesUsedPercent float64 `json:"inodes_used_percent"` InodesUsedPercent float64 `json:"inodesUsedPercent"`
} }
type DiskPartitionStat struct { type PartitionStat struct {
Device string `json:"device"` Device string `json:"device"`
Mountpoint string `json:"mountpoint"` Mountpoint string `json:"mountpoint"`
Fstype string `json:"fstype"` Fstype string `json:"fstype"`
Opts string `json:"opts"` Opts string `json:"opts"`
} }
type DiskIOCountersStat struct { type IOCountersStat struct {
ReadCount uint64 `json:"read_count"` ReadCount uint64 `json:"readCount"`
WriteCount uint64 `json:"write_count"` WriteCount uint64 `json:"writeCount"`
ReadBytes uint64 `json:"read_bytes"` ReadBytes uint64 `json:"readBytes"`
WriteBytes uint64 `json:"write_bytes"` WriteBytes uint64 `json:"writeBytes"`
ReadTime uint64 `json:"read_time"` ReadTime uint64 `json:"readTime"`
WriteTime uint64 `json:"write_time"` WriteTime uint64 `json:"writeTime"`
Name string `json:"name"` Name string `json:"name"`
IoTime uint64 `json:"io_time"` IoTime uint64 `json:"ioTime"`
SerialNumber string `json:"serial_number"` SerialNumber string `json:"serialNumber"`
} }
func (d DiskUsageStat) String() string { func (d UsageStat) String() string {
s, _ := json.Marshal(d) s, _ := json.Marshal(d)
return string(s) return string(s)
} }
func (d DiskPartitionStat) String() string { func (d PartitionStat) String() string {
s, _ := json.Marshal(d) s, _ := json.Marshal(d)
return string(s) return string(s)
} }
func (d DiskIOCountersStat) String() string { func (d IOCountersStat) String() string {
s, _ := json.Marshal(d) s, _ := json.Marshal(d)
return string(s) return string(s)
} }

@ -9,8 +9,8 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func DiskPartitions(all bool) ([]DiskPartitionStat, error) { func Partitions(all bool) ([]PartitionStat, error) {
var ret []DiskPartitionStat var ret []PartitionStat
count, err := Getfsstat(nil, MntWait) count, err := Getfsstat(nil, MntWait)
if err != nil { if err != nil {
@ -68,7 +68,7 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
if stat.Flags&MntNFS4ACLs != 0 { if stat.Flags&MntNFS4ACLs != 0 {
opts += ",nfs4acls" opts += ",nfs4acls"
} }
d := DiskPartitionStat{ d := PartitionStat{
Device: common.IntToString(stat.Mntfromname[:]), Device: common.IntToString(stat.Mntfromname[:]),
Mountpoint: common.IntToString(stat.Mntonname[:]), Mountpoint: common.IntToString(stat.Mntonname[:]),
Fstype: common.IntToString(stat.Fstypename[:]), Fstype: common.IntToString(stat.Fstypename[:]),
@ -80,8 +80,8 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
return ret, nil return ret, nil
} }
func DiskIOCounters() (map[string]DiskIOCountersStat, error) { func IOCounters() (map[string]IOCountersStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {

@ -12,8 +12,8 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func DiskPartitions(all bool) ([]DiskPartitionStat, error) { func Partitions(all bool) ([]PartitionStat, error) {
var ret []DiskPartitionStat var ret []PartitionStat
// get length // get length
count, err := syscall.Getfsstat(nil, MNT_WAIT) count, err := syscall.Getfsstat(nil, MNT_WAIT)
@ -75,7 +75,7 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
opts += ",nfs4acls" opts += ",nfs4acls"
} }
d := DiskPartitionStat{ d := PartitionStat{
Device: common.IntToString(stat.Mntfromname[:]), Device: common.IntToString(stat.Mntfromname[:]),
Mountpoint: common.IntToString(stat.Mntonname[:]), Mountpoint: common.IntToString(stat.Mntonname[:]),
Fstype: common.IntToString(stat.Fstypename[:]), Fstype: common.IntToString(stat.Fstypename[:]),
@ -87,10 +87,10 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
return ret, nil return ret, nil
} }
func DiskIOCounters() (map[string]DiskIOCountersStat, error) { func IOCounters() (map[string]IOCountersStat, error) {
// statinfo->devinfo->devstat // statinfo->devinfo->devstat
// /usr/include/devinfo.h // /usr/include/devinfo.h
ret := make(map[string]DiskIOCountersStat) ret := make(map[string]IOCountersStat)
r, err := syscall.Sysctl("kern.devstat.all") r, err := syscall.Sysctl("kern.devstat.all")
if err != nil { if err != nil {
@ -112,7 +112,7 @@ func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
un := strconv.Itoa(int(d.Unit_number)) un := strconv.Itoa(int(d.Unit_number))
name := common.IntToString(d.Device_name[:]) + un name := common.IntToString(d.Device_name[:]) + un
ds := DiskIOCountersStat{ ds := IOCountersStat{
ReadCount: d.Operations[DEVSTAT_READ], ReadCount: d.Operations[DEVSTAT_READ],
WriteCount: d.Operations[DEVSTAT_WRITE], WriteCount: d.Operations[DEVSTAT_WRITE],
ReadBytes: d.Bytes[DEVSTAT_READ], ReadBytes: d.Bytes[DEVSTAT_READ],

@ -95,7 +95,7 @@ type Devstat struct {
Flags uint32 Flags uint32
Device_type uint32 Device_type uint32
Priority uint32 Priority uint32
Id *byte ID *byte
Sequence1 uint32 Sequence1 uint32
} }
type Bintime struct { type Bintime struct {

@ -101,7 +101,7 @@ type Devstat struct {
Device_type uint32 Device_type uint32
Priority uint32 Priority uint32
Pad_cgo_1 [4]byte Pad_cgo_1 [4]byte
Id *byte ID *byte
Sequence1 uint32 Sequence1 uint32
Pad_cgo_2 [4]byte Pad_cgo_2 [4]byte
} }

@ -213,18 +213,18 @@ var fsTypeMap = map[int64]string{
// Get disk partitions. // Get disk partitions.
// should use setmntent(3) but this implement use /etc/mtab file // should use setmntent(3) but this implement use /etc/mtab file
func DiskPartitions(all bool) ([]DiskPartitionStat, error) { func Partitions(all bool) ([]PartitionStat, error) {
filename := common.HostEtc("mtab") filename := common.HostEtc("mtab")
lines, err := common.ReadLines(filename) lines, err := common.ReadLines(filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret := make([]DiskPartitionStat, 0, len(lines)) ret := make([]PartitionStat, 0, len(lines))
for _, line := range lines { for _, line := range lines {
fields := strings.Fields(line) fields := strings.Fields(line)
d := DiskPartitionStat{ d := PartitionStat{
Device: fields[0], Device: fields[0],
Mountpoint: fields[1], Mountpoint: fields[1],
Fstype: fields[2], Fstype: fields[2],
@ -236,14 +236,14 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
return ret, nil return ret, nil
} }
func DiskIOCounters() (map[string]DiskIOCountersStat, error) { func IOCounters() (map[string]IOCountersStat, error) {
filename := common.HostProc("diskstats") filename := common.HostProc("diskstats")
lines, err := common.ReadLines(filename) lines, err := common.ReadLines(filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret := make(map[string]DiskIOCountersStat, 0) ret := make(map[string]IOCountersStat, 0)
empty := DiskIOCountersStat{} empty := IOCountersStat{}
for _, line := range lines { for _, line := range lines {
fields := strings.Fields(line) fields := strings.Fields(line)
@ -276,7 +276,7 @@ func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
if err != nil { if err != nil {
return ret, err return ret, err
} }
d := DiskIOCountersStat{ d := IOCountersStat{
ReadBytes: rbytes * SectorSize, ReadBytes: rbytes * SectorSize,
WriteBytes: wbytes * SectorSize, WriteBytes: wbytes * SectorSize,
ReadCount: reads, ReadCount: reads,
@ -298,7 +298,12 @@ func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
func GetDiskSerialNumber(name string) string { func GetDiskSerialNumber(name string) string {
n := fmt.Sprintf("--name=%s", name) n := fmt.Sprintf("--name=%s", name)
out, err := exec.Command("/sbin/udevadm", "info", "--query=property", n).Output() udevadm, err := exec.LookPath("/sbin/udevadm")
if err != nil {
return ""
}
out, err := exec.Command(udevadm, "info", "--query=property", n).Output()
// does not return error, just an empty string // does not return error, just an empty string
if err != nil { if err != nil {

@ -11,7 +11,7 @@ func TestDisk_usage(t *testing.T) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
path = "C:" path = "C:"
} }
v, err := DiskUsage(path) v, err := Usage(path)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
@ -21,11 +21,11 @@ func TestDisk_usage(t *testing.T) {
} }
func TestDisk_partitions(t *testing.T) { func TestDisk_partitions(t *testing.T) {
ret, err := DiskPartitions(false) ret, err := Partitions(false)
if err != nil || len(ret) == 0 { if err != nil || len(ret) == 0 {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
empty := DiskPartitionStat{} empty := PartitionStat{}
for _, disk := range ret { for _, disk := range ret {
if disk == empty { if disk == empty {
t.Errorf("Could not get device info %v", disk) t.Errorf("Could not get device info %v", disk)
@ -34,14 +34,14 @@ func TestDisk_partitions(t *testing.T) {
} }
func TestDisk_io_counters(t *testing.T) { func TestDisk_io_counters(t *testing.T) {
ret, err := DiskIOCounters() ret, err := IOCounters()
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
if len(ret) == 0 { if len(ret) == 0 {
t.Errorf("ret is empty, %v", ret) t.Errorf("ret is empty, %v", ret)
} }
empty := DiskIOCountersStat{} empty := IOCountersStat{}
for part, io := range ret { for part, io := range ret {
if io == empty { if io == empty {
t.Errorf("io_counter error %v, %v", part, io) t.Errorf("io_counter error %v, %v", part, io)
@ -50,7 +50,7 @@ func TestDisk_io_counters(t *testing.T) {
} }
func TestDiskUsageStat_String(t *testing.T) { func TestDiskUsageStat_String(t *testing.T) {
v := DiskUsageStat{ v := UsageStat{
Path: "/", Path: "/",
Total: 1000, Total: 1000,
Free: 2000, Free: 2000,
@ -62,14 +62,14 @@ func TestDiskUsageStat_String(t *testing.T) {
InodesUsedPercent: 49.1, InodesUsedPercent: 49.1,
Fstype: "ext4", Fstype: "ext4",
} }
e := `{"path":"/","fstype":"ext4","total":1000,"free":2000,"used":3000,"used_percent":50.1,"inodes_total":4000,"inodes_used":5000,"inodes_free":6000,"inodes_used_percent":49.1}` e := `{"path":"/","fstype":"ext4","total":1000,"free":2000,"used":3000,"usedPercent":50.1,"inodesTotal":4000,"inodesUsed":5000,"inodesFree":6000,"inodesUsedPercent":49.1}`
if e != fmt.Sprintf("%v", v) { if e != fmt.Sprintf("%v", v) {
t.Errorf("DiskUsageStat string is invalid: %v", v) t.Errorf("DiskUsageStat string is invalid: %v", v)
} }
} }
func TestDiskPartitionStat_String(t *testing.T) { func TestDiskPartitionStat_String(t *testing.T) {
v := DiskPartitionStat{ v := PartitionStat{
Device: "sd01", Device: "sd01",
Mountpoint: "/", Mountpoint: "/",
Fstype: "ext4", Fstype: "ext4",
@ -82,7 +82,7 @@ func TestDiskPartitionStat_String(t *testing.T) {
} }
func TestDiskIOCountersStat_String(t *testing.T) { func TestDiskIOCountersStat_String(t *testing.T) {
v := DiskIOCountersStat{ v := IOCountersStat{
Name: "sd01", Name: "sd01",
ReadCount: 100, ReadCount: 100,
WriteCount: 200, WriteCount: 200,
@ -90,7 +90,7 @@ func TestDiskIOCountersStat_String(t *testing.T) {
WriteBytes: 400, WriteBytes: 400,
SerialNumber: "SERIAL", SerialNumber: "SERIAL",
} }
e := `{"read_count":100,"write_count":200,"read_bytes":300,"write_bytes":400,"read_time":0,"write_time":0,"name":"sd01","io_time":0,"serial_number":"SERIAL"}` e := `{"readCount":100,"writeCount":200,"readBytes":300,"writeBytes":400,"readTime":0,"writeTime":0,"name":"sd01","ioTime":0,"serialNumber":"SERIAL"}`
if e != fmt.Sprintf("%v", v) { if e != fmt.Sprintf("%v", v) {
t.Errorf("DiskUsageStat string is invalid: %v", v) t.Errorf("DiskUsageStat string is invalid: %v", v)
} }

@ -4,7 +4,7 @@ package disk
import "syscall" import "syscall"
func DiskUsage(path string) (*DiskUsageStat, error) { func Usage(path string) (*UsageStat, error) {
stat := syscall.Statfs_t{} stat := syscall.Statfs_t{}
err := syscall.Statfs(path, &stat) err := syscall.Statfs(path, &stat)
if err != nil { if err != nil {
@ -12,7 +12,7 @@ func DiskUsage(path string) (*DiskUsageStat, error) {
} }
bsize := stat.Bsize bsize := stat.Bsize
ret := &DiskUsageStat{ ret := &UsageStat{
Path: path, Path: path,
Fstype: getFsType(stat), Fstype: getFsType(stat),
Total: (uint64(stat.Blocks) * uint64(bsize)), Total: (uint64(stat.Blocks) * uint64(bsize)),

@ -36,8 +36,8 @@ type Win32_PerfFormattedData struct {
const WaitMSec = 500 const WaitMSec = 500
func DiskUsage(path string) (*DiskUsageStat, error) { func Usage(path string) (*UsageStat, error) {
ret := &DiskUsageStat{} ret := &UsageStat{}
lpFreeBytesAvailable := int64(0) lpFreeBytesAvailable := int64(0)
lpTotalNumberOfBytes := int64(0) lpTotalNumberOfBytes := int64(0)
@ -50,7 +50,7 @@ func DiskUsage(path string) (*DiskUsageStat, error) {
if diskret == 0 { if diskret == 0 {
return nil, err return nil, err
} }
ret = &DiskUsageStat{ ret = &UsageStat{
Path: path, Path: path,
Total: uint64(lpTotalNumberOfBytes), Total: uint64(lpTotalNumberOfBytes),
Free: uint64(lpTotalNumberOfFreeBytes), Free: uint64(lpTotalNumberOfFreeBytes),
@ -64,8 +64,8 @@ func DiskUsage(path string) (*DiskUsageStat, error) {
return ret, nil return ret, nil
} }
func DiskPartitions(all bool) ([]DiskPartitionStat, error) { func Partitions(all bool) ([]PartitionStat, error) {
var ret []DiskPartitionStat var ret []PartitionStat
lpBuffer := make([]byte, 254) lpBuffer := make([]byte, 254)
diskret, _, err := procGetLogicalDriveStringsW.Call( diskret, _, err := procGetLogicalDriveStringsW.Call(
uintptr(len(lpBuffer)), uintptr(len(lpBuffer)),
@ -116,7 +116,7 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
opts += ".compress" opts += ".compress"
} }
d := DiskPartitionStat{ d := PartitionStat{
Mountpoint: path, Mountpoint: path,
Device: path, Device: path,
Fstype: string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)), Fstype: string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)),
@ -129,8 +129,8 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
return ret, nil return ret, nil
} }
func DiskIOCounters() (map[string]DiskIOCountersStat, error) { func IOCounters() (map[string]IOCountersStat, error) {
ret := make(map[string]DiskIOCountersStat, 0) ret := make(map[string]IOCountersStat, 0)
var dst []Win32_PerfFormattedData var dst []Win32_PerfFormattedData
err := wmi.Query("SELECT * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk ", &dst) err := wmi.Query("SELECT * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk ", &dst)
@ -141,7 +141,7 @@ func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
if len(d.Name) > 3 { // not get _Total or Harddrive if len(d.Name) > 3 { // not get _Total or Harddrive
continue continue
} }
ret[d.Name] = DiskIOCountersStat{ ret[d.Name] = IOCountersStat{
Name: d.Name, Name: d.Name,
ReadCount: uint64(d.AvgDiskReadQueueLength), ReadCount: uint64(d.AvgDiskReadQueueLength),
WriteCount: d.AvgDiskWriteQueueLength, WriteCount: d.AvgDiskWriteQueueLength,

@ -6,36 +6,36 @@ var ErrDockerNotAvailable = errors.New("docker not available")
var ErrCgroupNotAvailable = errors.New("cgroup not available") var ErrCgroupNotAvailable = errors.New("cgroup not available")
type CgroupMemStat struct { type CgroupMemStat struct {
ContainerID string `json:"container_id"` ContainerID string `json:"containerID"`
Cache uint64 `json:"cache"` Cache uint64 `json:"cache"`
RSS uint64 `json:"rss"` RSS uint64 `json:"rss"`
RSSHuge uint64 `json:"rss_huge"` RSSHuge uint64 `json:"rssHuge"`
MappedFile uint64 `json:"mapped_file"` MappedFile uint64 `json:"mappedFile"`
Pgpgin uint64 `json:"pgpgin"` Pgpgin uint64 `json:"pgpgin"`
Pgpgout uint64 `json:"pgpgout"` Pgpgout uint64 `json:"pgpgout"`
Pgfault uint64 `json:"pgfault"` Pgfault uint64 `json:"pgfault"`
Pgmajfault uint64 `json:"pgmajfault"` Pgmajfault uint64 `json:"pgmajfault"`
InactiveAnon uint64 `json:"inactive_anon"` InactiveAnon uint64 `json:"inactiveAnon"`
ActiveAnon uint64 `json:"active_anon"` ActiveAnon uint64 `json:"activeAnon"`
InactiveFile uint64 `json:"inactive_file"` InactiveFile uint64 `json:"inactiveFile"`
ActiveFile uint64 `json:"active_file"` ActiveFile uint64 `json:"activeFile"`
Unevictable uint64 `json:"unevictable"` Unevictable uint64 `json:"unevictable"`
HierarchicalMemoryLimit uint64 `json:"hierarchical_memory_limit"` HierarchicalMemoryLimit uint64 `json:"hierarchicalMemoryLimit"`
TotalCache uint64 `json:"total_cache"` TotalCache uint64 `json:"totalCache"`
TotalRSS uint64 `json:"total_rss"` TotalRSS uint64 `json:"totalRss"`
TotalRSSHuge uint64 `json:"total_rss_huge"` TotalRSSHuge uint64 `json:"totalRssHuge"`
TotalMappedFile uint64 `json:"total_mapped_file"` TotalMappedFile uint64 `json:"totalMappedFile"`
TotalPgpgIn uint64 `json:"total_pgpgin"` TotalPgpgIn uint64 `json:"totalPgpgin"`
TotalPgpgOut uint64 `json:"total_pgpgout"` TotalPgpgOut uint64 `json:"totalPgpgout"`
TotalPgFault uint64 `json:"total_pgfault"` TotalPgFault uint64 `json:"totalPgfault"`
TotalPgMajFault uint64 `json:"total_pgmajfault"` TotalPgMajFault uint64 `json:"totalPgmajfault"`
TotalInactiveAnon uint64 `json:"total_inactive_anon"` TotalInactiveAnon uint64 `json:"totalInactiveAnon"`
TotalActiveAnon uint64 `json:"total_active_anon"` TotalActiveAnon uint64 `json:"totalActiveAnon"`
TotalInactiveFile uint64 `json:"total_inactive_file"` TotalInactiveFile uint64 `json:"totalInactiveFile"`
TotalActiveFile uint64 `json:"total_active_file"` TotalActiveFile uint64 `json:"totalActiveFile"`
TotalUnevictable uint64 `json:"total_unevictable"` TotalUnevictable uint64 `json:"totalUnevictable"`
MemUsageInBytes uint64 `json:"mem_usage_in_bytes"` MemUsageInBytes uint64 `json:"memUsageInBytes"`
MemMaxUsageInBytes uint64 `json:"mem_max_usage_in_bytes"` MemMaxUsageInBytes uint64 `json:"memMaxUsageInBytes"`
MemLimitInBytes uint64 `json:"memory.limit_in_bytes"` MemLimitInBytes uint64 `json:"memoryLimitInBbytes"`
MemFailCnt uint64 `json:"memory.failcnt"` MemFailCnt uint64 `json:"memoryFailcnt"`
} }

@ -41,20 +41,20 @@ func GetDockerIDList() ([]string, error) {
} }
// CgroupCPU returnes specified cgroup id CPU status. // CgroupCPU returnes specified cgroup id CPU status.
// containerId is same as docker id if you use docker. // containerID is same as docker id if you use docker.
// If you use container via systemd.slice, you could use // If you use container via systemd.slice, you could use
// containerId = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ // containerID = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
func CgroupCPU(containerId string, base string) (*cpu.CPUTimesStat, error) { func CgroupCPU(containerID string, base string) (*cpu.TimesStat, error) {
statfile := getCgroupFilePath(containerId, base, "cpuacct", "cpuacct.stat") statfile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.stat")
lines, err := common.ReadLines(statfile) lines, err := common.ReadLines(statfile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// empty containerId means all cgroup // empty containerID means all cgroup
if len(containerId) == 0 { if len(containerID) == 0 {
containerId = "all" containerID = "all"
} }
ret := &cpu.CPUTimesStat{CPU: containerId} ret := &cpu.TimesStat{CPU: containerID}
for _, line := range lines { for _, line := range lines {
fields := strings.Split(line, " ") fields := strings.Split(line, " ")
if fields[0] == "user" { if fields[0] == "user" {
@ -74,22 +74,22 @@ func CgroupCPU(containerId string, base string) (*cpu.CPUTimesStat, error) {
return ret, nil return ret, nil
} }
func CgroupCPUDocker(containerid string) (*cpu.CPUTimesStat, error) { func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) {
return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker")) return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
} }
func CgroupMem(containerId string, base string) (*CgroupMemStat, error) { func CgroupMem(containerID string, base string) (*CgroupMemStat, error) {
statfile := getCgroupFilePath(containerId, base, "memory", "memory.stat") statfile := getCgroupFilePath(containerID, base, "memory", "memory.stat")
// empty containerId means all cgroup // empty containerID means all cgroup
if len(containerId) == 0 { if len(containerID) == 0 {
containerId = "all" containerID = "all"
} }
lines, err := common.ReadLines(statfile) lines, err := common.ReadLines(statfile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret := &CgroupMemStat{ContainerID: containerId} ret := &CgroupMemStat{ContainerID: containerID}
for _, line := range lines { for _, line := range lines {
fields := strings.Split(line, " ") fields := strings.Split(line, " ")
v, err := strconv.ParseUint(fields[1], 10, 64) v, err := strconv.ParseUint(fields[1], 10, 64)
@ -101,9 +101,9 @@ func CgroupMem(containerId string, base string) (*CgroupMemStat, error) {
ret.Cache = v ret.Cache = v
case "rss": case "rss":
ret.RSS = v ret.RSS = v
case "rss_huge": case "rssHuge":
ret.RSSHuge = v ret.RSSHuge = v
case "mapped_file": case "mappedFile":
ret.MappedFile = v ret.MappedFile = v
case "pgpgin": case "pgpgin":
ret.Pgpgin = v ret.Pgpgin = v
@ -113,60 +113,60 @@ func CgroupMem(containerId string, base string) (*CgroupMemStat, error) {
ret.Pgfault = v ret.Pgfault = v
case "pgmajfault": case "pgmajfault":
ret.Pgmajfault = v ret.Pgmajfault = v
case "inactive_anon": case "inactiveAnon":
ret.InactiveAnon = v ret.InactiveAnon = v
case "active_anon": case "activeAnon":
ret.ActiveAnon = v ret.ActiveAnon = v
case "inactive_file": case "inactiveFile":
ret.InactiveFile = v ret.InactiveFile = v
case "active_file": case "activeFile":
ret.ActiveFile = v ret.ActiveFile = v
case "unevictable": case "unevictable":
ret.Unevictable = v ret.Unevictable = v
case "hierarchical_memory_limit": case "hierarchicalMemoryLimit":
ret.HierarchicalMemoryLimit = v ret.HierarchicalMemoryLimit = v
case "total_cache": case "totalCache":
ret.TotalCache = v ret.TotalCache = v
case "total_rss": case "totalRss":
ret.TotalRSS = v ret.TotalRSS = v
case "total_rss_huge": case "totalRssHuge":
ret.TotalRSSHuge = v ret.TotalRSSHuge = v
case "total_mapped_file": case "totalMappedFile":
ret.TotalMappedFile = v ret.TotalMappedFile = v
case "total_pgpgin": case "totalPgpgin":
ret.TotalPgpgIn = v ret.TotalPgpgIn = v
case "total_pgpgout": case "totalPgpgout":
ret.TotalPgpgOut = v ret.TotalPgpgOut = v
case "total_pgfault": case "totalPgfault":
ret.TotalPgFault = v ret.TotalPgFault = v
case "total_pgmajfault": case "totalPgmajfault":
ret.TotalPgMajFault = v ret.TotalPgMajFault = v
case "total_inactive_anon": case "totalInactiveAnon":
ret.TotalInactiveAnon = v ret.TotalInactiveAnon = v
case "total_active_anon": case "totalActiveAnon":
ret.TotalActiveAnon = v ret.TotalActiveAnon = v
case "total_inactive_file": case "totalInactiveFile":
ret.TotalInactiveFile = v ret.TotalInactiveFile = v
case "total_active_file": case "totalActiveFile":
ret.TotalActiveFile = v ret.TotalActiveFile = v
case "total_unevictable": case "totalUnevictable":
ret.TotalUnevictable = v ret.TotalUnevictable = v
} }
} }
r, err := getCgroupMemFile(containerId, base, "memory.usage_in_bytes") r, err := getCgroupMemFile(containerID, base, "memory.usage_in_bytes")
if err == nil { if err == nil {
ret.MemUsageInBytes = r ret.MemUsageInBytes = r
} }
r, err = getCgroupMemFile(containerId, base, "memory.max_usage_in_bytes") r, err = getCgroupMemFile(containerID, base, "memory.max_usage_in_bytes")
if err == nil { if err == nil {
ret.MemMaxUsageInBytes = r ret.MemMaxUsageInBytes = r
} }
r, err = getCgroupMemFile(containerId, base, "memory.limit_in_bytes") r, err = getCgroupMemFile(containerID, base, "memoryLimitInBbytes")
if err == nil { if err == nil {
ret.MemLimitInBytes = r ret.MemLimitInBytes = r
} }
r, err = getCgroupMemFile(containerId, base, "memory.failcnt") r, err = getCgroupMemFile(containerID, base, "memoryFailcnt")
if err == nil { if err == nil {
ret.MemFailCnt = r ret.MemFailCnt = r
} }
@ -174,8 +174,8 @@ func CgroupMem(containerId string, base string) (*CgroupMemStat, error) {
return ret, nil return ret, nil
} }
func CgroupMemDocker(containerId string) (*CgroupMemStat, error) { func CgroupMemDocker(containerID string) (*CgroupMemStat, error) {
return CgroupMem(containerId, common.HostSys("fs/cgroup/memory/docker")) return CgroupMem(containerID, common.HostSys("fs/cgroup/memory/docker"))
} }
func (m CgroupMemStat) String() string { func (m CgroupMemStat) String() string {
@ -184,24 +184,23 @@ func (m CgroupMemStat) String() string {
} }
// getCgroupFilePath constructs file path to get targetted stats file. // getCgroupFilePath constructs file path to get targetted stats file.
func getCgroupFilePath(containerId, base, target, file string) string { func getCgroupFilePath(containerID, base, target, file string) string {
if len(base) == 0 { if len(base) == 0 {
base = common.HostSys(fmt.Sprintf("fs/cgroup/%s/docker", target)) base = common.HostSys(fmt.Sprintf("fs/cgroup/%s/docker", target))
} }
statfile := path.Join(base, containerId, file) statfile := path.Join(base, containerID, file)
if _, err := os.Stat(statfile); os.IsNotExist(err) { if _, err := os.Stat(statfile); os.IsNotExist(err) {
statfile = path.Join( statfile = path.Join(
common.HostSys(fmt.Sprintf("fs/cgroup/%s/system.slice", target)), "docker-"+containerId+".scope", file) common.HostSys(fmt.Sprintf("fs/cgroup/%s/system.slice", target)), "docker-"+containerID+".scope", file)
} }
return statfile return statfile
} }
// getCgroupMemFile reads a cgroup file and return the contents as uint64. // getCgroupMemFile reads a cgroup file and return the contents as uint64.
func getCgroupMemFile(containerId, base, file string) (uint64, error) { func getCgroupMemFile(containerID, base, file string) (uint64, error) {
statfile := getCgroupFilePath(containerID, base, "memory", file)
statfile := getCgroupFilePath(containerId, base, "memory", file)
lines, err := common.ReadLines(statfile) lines, err := common.ReadLines(statfile)
if err != nil { if err != nil {
return 0, err return 0, err

@ -19,11 +19,11 @@ func GetDockerIDList() ([]string, error) {
// containerid is same as docker id if you use docker. // containerid is same as docker id if you use docker.
// If you use container via systemd.slice, you could use // If you use container via systemd.slice, you could use
// containerid = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ // containerid = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
func CgroupCPU(containerid string, base string) (*cpu.CPUTimesStat, error) { func CgroupCPU(containerid string, base string) (*cpu.TimesStat, error) {
return nil, ErrCgroupNotAvailable return nil, ErrCgroupNotAvailable
} }
func CgroupCPUDocker(containerid string) (*cpu.CPUTimesStat, error) { func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) {
return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker")) return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
} }

@ -6,17 +6,17 @@ import (
// A HostInfoStat describes the host status. // A HostInfoStat describes the host status.
// This is not in the psutil but it useful. // This is not in the psutil but it useful.
type HostInfoStat struct { type InfoStat struct {
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
Uptime uint64 `json:"uptime"` Uptime uint64 `json:"uptime"`
BootTime uint64 `json:"boot_time"` BootTime uint64 `json:"bootTime"`
Procs uint64 `json:"procs"` // number of processes Procs uint64 `json:"procs"` // number of processes
OS string `json:"os"` // ex: freebsd, linux OS string `json:"os"` // ex: freebsd, linux
Platform string `json:"platform"` // ex: ubuntu, linuxmint Platform string `json:"platform"` // ex: ubuntu, linuxmint
PlatformFamily string `json:"platform_family"` // ex: debian, rhel PlatformFamily string `json:"platformFamily"` // ex: debian, rhel
PlatformVersion string `json:"platform_version"` PlatformVersion string `json:"platformVersion"`
VirtualizationSystem string `json:"virtualization_system"` VirtualizationSystem string `json:"virtualizationSystem"`
VirtualizationRole string `json:"virtualization_role"` // guest or host VirtualizationRole string `json:"virtualizationRole"` // guest or host
} }
@ -27,7 +27,7 @@ type UserStat struct {
Started int `json:"started"` Started int `json:"started"`
} }
func (h HostInfoStat) String() string { func (h InfoStat) String() string {
s, _ := json.Marshal(h) s, _ := json.Marshal(h)
return string(s) return string(s)
} }

@ -20,8 +20,8 @@ import (
// from utmpx.h // from utmpx.h
const USER_PROCESS = 7 const USER_PROCESS = 7
func HostInfo() (*HostInfoStat, error) { func Info() (*InfoStat, error) {
ret := &HostInfoStat{ ret := &InfoStat{
OS: runtime.GOOS, OS: runtime.GOOS,
PlatformFamily: "darwin", PlatformFamily: "darwin",
} }
@ -31,13 +31,13 @@ func HostInfo() (*HostInfoStat, error) {
ret.Hostname = hostname ret.Hostname = hostname
} }
platform, family, version, err := GetPlatformInformation() platform, family, version, err := PlatformInformation()
if err == nil { if err == nil {
ret.Platform = platform ret.Platform = platform
ret.PlatformFamily = family ret.PlatformFamily = family
ret.PlatformVersion = version ret.PlatformVersion = version
} }
system, role, err := GetVirtualization() system, role, err := Virtualization()
if err == nil { if err == nil {
ret.VirtualizationSystem = system ret.VirtualizationSystem = system
ret.VirtualizationRole = role ret.VirtualizationRole = role
@ -122,17 +122,21 @@ func Users() ([]UserStat, error) {
} }
func GetPlatformInformation() (string, string, string, error) { func PlatformInformation() (string, string, string, error) {
platform := "" platform := ""
family := "" family := ""
version := "" version := ""
out, err := exec.Command("uname", "-s").Output() uname, err := exec.LookPath("uname")
if err != nil {
return "", "", "", err
}
out, err := exec.Command(uname, "-s").Output()
if err == nil { if err == nil {
platform = strings.ToLower(strings.TrimSpace(string(out))) platform = strings.ToLower(strings.TrimSpace(string(out)))
} }
out, err = exec.Command("uname", "-r").Output() out, err = exec.Command(uname, "-r").Output()
if err == nil { if err == nil {
version = strings.ToLower(strings.TrimSpace(string(out))) version = strings.ToLower(strings.TrimSpace(string(out)))
} }
@ -140,7 +144,7 @@ func GetPlatformInformation() (string, string, string, error) {
return platform, family, version, nil return platform, family, version, nil
} }
func GetVirtualization() (string, string, error) { func Virtualization() (string, string, error) {
system := "" system := ""
role := "" role := ""

@ -5,7 +5,7 @@ package host
type Utmpx struct { type Utmpx struct {
User [256]int8 User [256]int8
Id [4]int8 ID [4]int8
Line [32]int8 Line [32]int8
Pid int32 Pid int32
Type int16 Type int16

@ -23,8 +23,8 @@ const (
UTHostSize = 16 UTHostSize = 16
) )
func HostInfo() (*HostInfoStat, error) { func Info() (*InfoStat, error) {
ret := &HostInfoStat{ ret := &InfoStat{
OS: runtime.GOOS, OS: runtime.GOOS,
PlatformFamily: "freebsd", PlatformFamily: "freebsd",
} }
@ -34,13 +34,13 @@ func HostInfo() (*HostInfoStat, error) {
ret.Hostname = hostname ret.Hostname = hostname
} }
platform, family, version, err := GetPlatformInformation() platform, family, version, err := PlatformInformation()
if err == nil { if err == nil {
ret.Platform = platform ret.Platform = platform
ret.PlatformFamily = family ret.PlatformFamily = family
ret.PlatformVersion = version ret.PlatformVersion = version
} }
system, role, err := GetVirtualization() system, role, err := Virtualization()
if err == nil { if err == nil {
ret.VirtualizationSystem = system ret.VirtualizationSystem = system
ret.VirtualizationRole = role ret.VirtualizationRole = role
@ -129,17 +129,21 @@ func Users() ([]UserStat, error) {
} }
func GetPlatformInformation() (string, string, string, error) { func PlatformInformation() (string, string, string, error) {
platform := "" platform := ""
family := "" family := ""
version := "" version := ""
uname, err := exec.LookPath("uname")
if err != nil {
return "", "", "", err
}
out, err := exec.Command("uname", "-s").Output() out, err := exec.Command(uname, "-s").Output()
if err == nil { if err == nil {
platform = strings.ToLower(strings.TrimSpace(string(out))) platform = strings.ToLower(strings.TrimSpace(string(out)))
} }
out, err = exec.Command("uname", "-r").Output() out, err = exec.Command(uname, "-r").Output()
if err == nil { if err == nil {
version = strings.ToLower(strings.TrimSpace(string(out))) version = strings.ToLower(strings.TrimSpace(string(out)))
} }
@ -147,7 +151,7 @@ func GetPlatformInformation() (string, string, string, error) {
return platform, family, version, nil return platform, family, version, nil
} }
func GetVirtualization() (string, string, error) { func Virtualization() (string, string, error) {
system := "" system := ""
role := "" role := ""

@ -27,7 +27,7 @@ type Utmp struct {
type Utmpx struct { type Utmpx struct {
Type int16 Type int16
Tv Timeval Tv Timeval
Id [8]int8 ID [8]int8
Pid int32 Pid int32
User [32]int8 User [32]int8
Line [16]int8 Line [16]int8

@ -29,8 +29,8 @@ type LSB struct {
// from utmp.h // from utmp.h
const USER_PROCESS = 7 const USER_PROCESS = 7
func HostInfo() (*HostInfoStat, error) { func Info() (*InfoStat, error) {
ret := &HostInfoStat{ ret := &InfoStat{
OS: runtime.GOOS, OS: runtime.GOOS,
} }
@ -39,13 +39,13 @@ func HostInfo() (*HostInfoStat, error) {
ret.Hostname = hostname ret.Hostname = hostname
} }
platform, family, version, err := GetPlatformInformation() platform, family, version, err := PlatformInformation()
if err == nil { if err == nil {
ret.Platform = platform ret.Platform = platform
ret.PlatformFamily = family ret.PlatformFamily = family
ret.PlatformVersion = version ret.PlatformVersion = version
} }
system, role, err := GetVirtualization() system, role, err := Virtualization()
if err == nil { if err == nil {
ret.VirtualizationSystem = system ret.VirtualizationSystem = system
ret.VirtualizationRole = role ret.VirtualizationRole = role
@ -163,7 +163,11 @@ func getLSB() (*LSB, error) {
} }
} }
} else if common.PathExists("/usr/bin/lsb_release") { } else if common.PathExists("/usr/bin/lsb_release") {
out, err := exec.Command("/usr/bin/lsb_release").Output() lsb_release, err := exec.LookPath("/usr/bin/lsb_release")
if err != nil {
return ret, err
}
out, err := exec.Command(lsb_release).Output()
if err != nil { if err != nil {
return ret, err return ret, err
} }
@ -189,7 +193,7 @@ func getLSB() (*LSB, error) {
return ret, nil return ret, nil
} }
func GetPlatformInformation() (platform string, family string, version string, err error) { func PlatformInformation() (platform string, family string, version string, err error) {
lsb, err := getLSB() lsb, err := getLSB()
if err != nil { if err != nil {
@ -338,7 +342,7 @@ func getSusePlatform(contents []string) string {
return "suse" return "suse"
} }
func GetVirtualization() (string, string, error) { func Virtualization() (string, string, error) {
var system string var system string
var role string var role string

@ -25,7 +25,7 @@ type utmp struct {
Pad_cgo_0 [2]byte Pad_cgo_0 [2]byte
Pid int32 Pid int32
Line [32]int8 Line [32]int8
Id [4]int8 ID [4]int8
User [32]int8 User [32]int8
Host [256]int8 Host [256]int8
Exit exit_status Exit exit_status

@ -23,7 +23,7 @@ type utmp struct {
Pad_cgo_0 [2]byte Pad_cgo_0 [2]byte
Pid int32 Pid int32
Line [32]int8 Line [32]int8
Id [4]int8 ID [4]int8
User [32]int8 User [32]int8
Host [256]int8 Host [256]int8
Exit exit_status Exit exit_status

@ -23,7 +23,7 @@ type utmp struct {
Pad_cgo_0 [2]byte Pad_cgo_0 [2]byte
Pid int32 Pid int32
Line [32]int8 Line [32]int8
Id [4]int8 ID [4]int8
User [32]int8 User [32]int8
Host [256]int8 Host [256]int8
Exit exit_status Exit exit_status

@ -6,11 +6,11 @@ import (
) )
func TestHostInfo(t *testing.T) { func TestHostInfo(t *testing.T) {
v, err := HostInfo() v, err := Info()
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
empty := &HostInfoStat{} empty := &InfoStat{}
if v == empty { if v == empty {
t.Errorf("Could not get hostinfo %v", v) t.Errorf("Could not get hostinfo %v", v)
} }
@ -40,7 +40,7 @@ func TestUsers(t *testing.T) {
} }
func TestHostInfoStat_String(t *testing.T) { func TestHostInfoStat_String(t *testing.T) {
v := HostInfoStat{ v := InfoStat{
Hostname: "test", Hostname: "test",
Uptime: 3000, Uptime: 3000,
Procs: 100, Procs: 100,
@ -48,7 +48,7 @@ func TestHostInfoStat_String(t *testing.T) {
Platform: "ubuntu", Platform: "ubuntu",
BootTime: 1447040000, BootTime: 1447040000,
} }
e := `{"hostname":"test","uptime":3000,"boot_time":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platform_family":"","platform_version":"","virtualization_system":"","virtualization_role":""}` e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","virtualizationSystem":"","virtualizationRole":""}`
if e != fmt.Sprintf("%v", v) { if e != fmt.Sprintf("%v", v) {
t.Errorf("HostInfoStat string is invalid: %v", v) t.Errorf("HostInfoStat string is invalid: %v", v)
} }

@ -28,8 +28,8 @@ type Win32_OperatingSystem struct {
LastBootUpTime time.Time LastBootUpTime time.Time
} }
func HostInfo() (*HostInfoStat, error) { func Info() (*InfoStat, error) {
ret := &HostInfoStat{ ret := &InfoStat{
OS: runtime.GOOS, OS: runtime.GOOS,
} }
@ -38,7 +38,7 @@ func HostInfo() (*HostInfoStat, error) {
ret.Hostname = hostname ret.Hostname = hostname
} }
platform, family, version, err := GetPlatformInformation() platform, family, version, err := PlatformInformation()
if err == nil { if err == nil {
ret.Platform = platform ret.Platform = platform
ret.PlatformFamily = family ret.PlatformFamily = family
@ -100,7 +100,7 @@ func Uptime() (uint64, error) {
return uptime(boot), nil return uptime(boot), nil
} }
func GetPlatformInformation() (platform string, family string, version string, err error) { func PlatformInformation() (platform string, family string, version string, err error) {
if osInfo == nil { if osInfo == nil {
_, err = GetOSInfo() _, err = GetOSInfo()
if err != nil { if err != nil {

@ -1,3 +1,5 @@
package common
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@ -19,8 +21,6 @@
// high-performance serialization, especially for large data structures, // high-performance serialization, especially for large data structures,
// should look at more advanced solutions such as the encoding/gob // should look at more advanced solutions such as the encoding/gob
// package or protocol buffers. // package or protocol buffers.
package common
import ( import (
"errors" "errors"
"io" "io"

@ -1,11 +1,11 @@
package common
// //
// gopsutil is a port of psutil(http://pythonhosted.org/psutil/). // gopsutil is a port of psutil(http://pythonhosted.org/psutil/).
// This covers these architectures. // This covers these architectures.
// - linux (amd64, arm) // - linux (amd64, arm)
// - freebsd (amd64) // - freebsd (amd64)
// - windows (amd64) // - windows (amd64)
package common
import ( import (
"bufio" "bufio"
"errors" "errors"
@ -59,12 +59,11 @@ func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) {
} }
if PathExists(fpath) { if PathExists(fpath) {
return ioutil.ReadFile(fpath) return ioutil.ReadFile(fpath)
} else {
return exec.Command(name, arg...).Output()
} }
return exec.Command(name, arg...).Output()
} }
var NotImplementedError = errors.New("not implemented yet") var ErrNotImplementedError = errors.New("not implemented yet")
// ReadLines reads contents from a file and splits them by new lines. // ReadLines reads contents from a file and splits them by new lines.
// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1). // A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).

@ -11,8 +11,16 @@ import (
) )
func DoSysctrl(mib string) ([]string, error) { func DoSysctrl(mib string) ([]string, error) {
os.Setenv("LC_ALL", "C") err := os.Setenv("LC_ALL", "C")
out, err := exec.Command("/usr/sbin/sysctl", "-n", mib).Output() if err != nil {
return []string{}, err
}
sysctl, err := exec.LookPath("/usr/sbin/sysctl")
if err != nil {
return []string{}, err
}
out, err := exec.Command(sysctl, "-n", mib).Output()
if err != nil { if err != nil {
return []string{}, err return []string{}, err
} }

@ -11,8 +11,15 @@ import (
) )
func DoSysctrl(mib string) ([]string, error) { func DoSysctrl(mib string) ([]string, error) {
os.Setenv("LC_ALL", "C") err := os.Setenv("LC_ALL", "C")
out, err := exec.Command("/sbin/sysctl", "-n", mib).Output() if err != nil {
return []string{}, err
}
sysctl, err := exec.LookPath("/sbin/sysctl")
if err != nil {
return []string{}, err
}
out, err := exec.Command(sysctl, "-n", mib).Output()
if err != nil { if err != nil {
return []string{}, err return []string{}, err
} }

@ -12,13 +12,13 @@ func init() {
invoke = common.Invoke{} invoke = common.Invoke{}
} }
type LoadAvgStat struct { type AvgStat struct {
Load1 float64 `json:"load1"` Load1 float64 `json:"load1"`
Load5 float64 `json:"load5"` Load5 float64 `json:"load5"`
Load15 float64 `json:"load15"` Load15 float64 `json:"load15"`
} }
func (l LoadAvgStat) String() string { func (l AvgStat) String() string {
s, _ := json.Marshal(l) s, _ := json.Marshal(l)
return string(s) return string(s)
} }

@ -10,7 +10,7 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func LoadAvg() (*LoadAvgStat, error) { func Avg() (*AvgStat, error) {
values, err := common.DoSysctrl("vm.loadavg") values, err := common.DoSysctrl("vm.loadavg")
if err != nil { if err != nil {
return nil, err return nil, err
@ -29,7 +29,7 @@ func LoadAvg() (*LoadAvgStat, error) {
return nil, err return nil, err
} }
ret := &LoadAvgStat{ ret := &AvgStat{
Load1: float64(load1), Load1: float64(load1),
Load5: float64(load5), Load5: float64(load5),
Load15: float64(load15), Load15: float64(load15),
@ -38,7 +38,6 @@ func LoadAvg() (*LoadAvgStat, error) {
return ret, nil return ret, nil
} }
// Misc returnes miscellaneous host-wide statistics. // Misc returnes miscellaneous host-wide statistics.
// darwin use ps command to get process running/blocked count. // darwin use ps command to get process running/blocked count.
// Almost same as FreeBSD implementation, but state is different. // Almost same as FreeBSD implementation, but state is different.
@ -57,10 +56,10 @@ func Misc() (*MiscStat, error) {
ret := MiscStat{} ret := MiscStat{}
for _, l := range lines { for _, l := range lines {
if strings.Contains(l, "R") { if strings.Contains(l, "R") {
ret.ProcsRunning += 1 ret.ProcsRunning++
} else if strings.Contains(l, "U") { } else if strings.Contains(l, "U") {
// uninterruptible sleep == blocked // uninterruptible sleep == blocked
ret.ProcsBlocked += 1 ret.ProcsBlocked++
} }
} }

@ -10,7 +10,7 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func LoadAvg() (*LoadAvgStat, error) { func Avg() (*AvgStat, error) {
values, err := common.DoSysctrl("vm.loadavg") values, err := common.DoSysctrl("vm.loadavg")
if err != nil { if err != nil {
return nil, err return nil, err
@ -29,7 +29,7 @@ func LoadAvg() (*LoadAvgStat, error) {
return nil, err return nil, err
} }
ret := &LoadAvgStat{ ret := &AvgStat{
Load1: float64(load1), Load1: float64(load1),
Load5: float64(load5), Load5: float64(load5),
Load15: float64(load15), Load15: float64(load15),
@ -55,9 +55,9 @@ func Misc() (*MiscStat, error) {
ret := MiscStat{} ret := MiscStat{}
for _, l := range lines { for _, l := range lines {
if strings.Contains(l, "R") { if strings.Contains(l, "R") {
ret.ProcsRunning += 1 ret.ProcsRunning++
} else if strings.Contains(l, "D") { } else if strings.Contains(l, "D") {
ret.ProcsBlocked += 1 ret.ProcsBlocked++
} }
} }

@ -10,7 +10,7 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func LoadAvg() (*LoadAvgStat, error) { func Avg() (*AvgStat, error) {
filename := common.HostProc("loadavg") filename := common.HostProc("loadavg")
line, err := ioutil.ReadFile(filename) line, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {
@ -32,7 +32,7 @@ func LoadAvg() (*LoadAvgStat, error) {
return nil, err return nil, err
} }
ret := &LoadAvgStat{ ret := &AvgStat{
Load1: load1, Load1: load1,
Load5: load5, Load5: load5,
Load15: load15, Load15: load15,
@ -41,7 +41,6 @@ func LoadAvg() (*LoadAvgStat, error) {
return ret, nil return ret, nil
} }
// Misc returnes miscellaneous host-wide statistics. // Misc returnes miscellaneous host-wide statistics.
// Note: the name should be changed near future. // Note: the name should be changed near future.
func Misc() (*MiscStat, error) { func Misc() (*MiscStat, error) {

@ -6,19 +6,19 @@ import (
) )
func TestLoad(t *testing.T) { func TestLoad(t *testing.T) {
v, err := LoadAvg() v, err := Avg()
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
empty := &LoadAvgStat{} empty := &AvgStat{}
if v == empty { if v == empty {
t.Errorf("error load: %v", v) t.Errorf("error load: %v", v)
} }
} }
func TestLoadAvgStat_String(t *testing.T) { func TestLoadAvgStat_String(t *testing.T) {
v := LoadAvgStat{ v := AvgStat{
Load1: 10.1, Load1: 10.1,
Load5: 20.1, Load5: 20.1,
Load15: 30.1, Load15: 30.1,

@ -6,14 +6,14 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func LoadAvg() (*LoadAvgStat, error) { func Avg() (*AvgStat, error) {
ret := LoadAvgStat{} ret := AvgStat{}
return &ret, common.NotImplementedError return &ret, common.ErrNotImplementedError
} }
func Misc() (*MiscStat, error) { func Misc() (*MiscStat, error) {
ret := MiscStat{} ret := MiscStat{}
return &ret, common.NotImplementedError return &ret, common.ErrNotImplementedError
} }

@ -25,7 +25,7 @@ type VirtualMemoryStat struct {
// Percentage of RAM used by programs // Percentage of RAM used by programs
// //
// This value is computed from the kernel specific values. // This value is computed from the kernel specific values.
UsedPercent float64 `json:"used_percent"` UsedPercent float64 `json:"usedPercent"`
// This is the kernel's notion of free memory; RAM chips whose bits nobody // This is the kernel's notion of free memory; RAM chips whose bits nobody
// cares about the value of right now. For a human consumable number, // cares about the value of right now. For a human consumable number,
@ -48,7 +48,7 @@ type SwapMemoryStat struct {
Total uint64 `json:"total"` Total uint64 `json:"total"`
Used uint64 `json:"used"` Used uint64 `json:"used"`
Free uint64 `json:"free"` Free uint64 `json:"free"`
UsedPercent float64 `json:"used_percent"` UsedPercent float64 `json:"usedPercent"`
Sin uint64 `json:"sin"` Sin uint64 `json:"sin"`
Sout uint64 `json:"sout"` Sout uint64 `json:"sout"`
} }

@ -12,7 +12,11 @@ import (
// Runs vm_stat and returns Free and inactive pages // Runs vm_stat and returns Free and inactive pages
func getVMStat(vms *VirtualMemoryStat) error { func getVMStat(vms *VirtualMemoryStat) error {
out, err := exec.Command("vm_stat").Output() vm_stat, err := exec.LookPath("vm_stat")
if err != nil {
return err
}
out, err := exec.Command(vm_stat).Output()
if err != nil { if err != nil {
return err return err
} }

@ -88,7 +88,12 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
// Return swapinfo // Return swapinfo
// FreeBSD can have multiple swap devices. but use only first device // FreeBSD can have multiple swap devices. but use only first device
func SwapMemory() (*SwapMemoryStat, error) { func SwapMemory() (*SwapMemoryStat, error) {
out, err := exec.Command("swapinfo").Output() swapinfo, err := exec.LookPath("swapinfo")
if err != nil {
return nil, err
}
out, err := exec.Command(swapinfo).Output()
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -52,7 +52,7 @@ func TestVirtualMemoryStat_String(t *testing.T) {
UsedPercent: 30.1, UsedPercent: 30.1,
Free: 40, Free: 40,
} }
e := `{"total":10,"available":20,"used":30,"used_percent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"buffers":0,"cached":0}` e := `{"total":10,"available":20,"used":30,"usedPercent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"buffers":0,"cached":0}`
if e != fmt.Sprintf("%v", v) { if e != fmt.Sprintf("%v", v) {
t.Errorf("VirtualMemoryStat string is invalid: %v", v) t.Errorf("VirtualMemoryStat string is invalid: %v", v)
} }
@ -65,7 +65,7 @@ func TestSwapMemoryStat_String(t *testing.T) {
Free: 40, Free: 40,
UsedPercent: 30.1, UsedPercent: 30.1,
} }
e := `{"total":10,"used":30,"free":40,"used_percent":30.1,"sin":0,"sout":0}` e := `{"total":10,"used":30,"free":40,"usedPercent":30.1,"sin":0,"sout":0}`
if e != fmt.Sprintf("%v", v) { if e != fmt.Sprintf("%v", v) {
t.Errorf("SwapMemoryStat string is invalid: %v", v) t.Errorf("SwapMemoryStat string is invalid: %v", v)
} }

@ -13,7 +13,7 @@ var (
procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx") procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx")
) )
type MEMORYSTATUSEX struct { type memoryStatusEx struct {
cbSize uint32 cbSize uint32
dwMemoryLoad uint32 dwMemoryLoad uint32
ullTotalPhys uint64 // in bytes ullTotalPhys uint64 // in bytes
@ -26,7 +26,7 @@ type MEMORYSTATUSEX struct {
} }
func VirtualMemory() (*VirtualMemoryStat, error) { func VirtualMemory() (*VirtualMemoryStat, error) {
var memInfo MEMORYSTATUSEX var memInfo memoryStatusEx
memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
if mem == 0 { if mem == 0 {

@ -17,12 +17,12 @@ func init() {
invoke = common.Invoke{} invoke = common.Invoke{}
} }
type NetIOCountersStat struct { type IOCountersStat struct {
Name string `json:"name"` // interface name Name string `json:"name"` // interface name
BytesSent uint64 `json:"bytes_sent"` // number of bytes sent BytesSent uint64 `json:"bytesSent"` // number of bytes sent
BytesRecv uint64 `json:"bytes_recv"` // number of bytes received BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
PacketsSent uint64 `json:"packets_sent"` // number of packets sent PacketsSent uint64 `json:"packetsSent"` // number of packets sent
PacketsRecv uint64 `json:"packets_recv"` // number of packets received PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
Errin uint64 `json:"errin"` // total number of errors while receiving Errin uint64 `json:"errin"` // total number of errors while receiving
Errout uint64 `json:"errout"` // total number of errors while sending Errout uint64 `json:"errout"` // total number of errors while sending
Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped
@ -35,7 +35,7 @@ type Addr struct {
Port uint32 `json:"port"` Port uint32 `json:"port"`
} }
type NetConnectionStat struct { type ConnectionStat struct {
Fd uint32 `json:"fd"` Fd uint32 `json:"fd"`
Family uint32 `json:"family"` Family uint32 `json:"family"`
Type uint32 `json:"type"` Type uint32 `json:"type"`
@ -46,27 +46,27 @@ type NetConnectionStat struct {
} }
// System wide stats about different network protocols // System wide stats about different network protocols
type NetProtoCountersStat struct { type ProtoCountersStat struct {
Protocol string `json:"protocol"` Protocol string `json:"protocol"`
Stats map[string]int64 `json:"stats"` Stats map[string]int64 `json:"stats"`
} }
// NetInterfaceAddr is designed for represent interface addresses // NetInterfaceAddr is designed for represent interface addresses
type NetInterfaceAddr struct { type InterfaceAddr struct {
Addr string `json:"addr"` Addr string `json:"addr"`
} }
type NetInterfaceStat struct { type InterfaceStat struct {
MTU int `json:"mtu"` // maximum transmission unit MTU int `json:"mtu"` // maximum transmission unit
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100" Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
HardwareAddr string `json:"hardwareaddr"` // IEEE MAC-48, EUI-48 and EUI-64 form HardwareAddr string `json:"hardwareaddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
Flags []string `json:"flags"` // e.g., FlagUp, FlagLoopback, FlagMulticast Flags []string `json:"flags"` // e.g., FlagUp, FlagLoopback, FlagMulticast
Addrs []NetInterfaceAddr `json:"addrs"` Addrs []InterfaceAddr `json:"addrs"`
} }
type NetFilterStat struct { type FilterStat struct {
ConnTrackCount int64 `json:"conntrack_count"` ConnTrackCount int64 `json:"conntrackCount"`
ConnTrackMax int64 `json:"conntrack_max"` ConnTrackMax int64 `json:"conntrackMax"`
} }
var constMap = map[string]int{ var constMap = map[string]int{
@ -76,17 +76,17 @@ var constMap = map[string]int{
"IPv6": syscall.AF_INET6, "IPv6": syscall.AF_INET6,
} }
func (n NetIOCountersStat) String() string { func (n IOCountersStat) String() string {
s, _ := json.Marshal(n) s, _ := json.Marshal(n)
return string(s) return string(s)
} }
func (n NetConnectionStat) String() string { func (n ConnectionStat) String() string {
s, _ := json.Marshal(n) s, _ := json.Marshal(n)
return string(s) return string(s)
} }
func (n NetProtoCountersStat) String() string { func (n ProtoCountersStat) String() string {
s, _ := json.Marshal(n) s, _ := json.Marshal(n)
return string(s) return string(s)
} }
@ -96,22 +96,22 @@ func (a Addr) String() string {
return string(s) return string(s)
} }
func (n NetInterfaceStat) String() string { func (n InterfaceStat) String() string {
s, _ := json.Marshal(n) s, _ := json.Marshal(n)
return string(s) return string(s)
} }
func (n NetInterfaceAddr) String() string { func (n InterfaceAddr) String() string {
s, _ := json.Marshal(n) s, _ := json.Marshal(n)
return string(s) return string(s)
} }
func NetInterfaces() ([]NetInterfaceStat, error) { func Interfaces() ([]InterfaceStat, error) {
is, err := net.Interfaces() is, err := net.Interfaces()
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret := make([]NetInterfaceStat, 0, len(is)) ret := make([]InterfaceStat, 0, len(is))
for _, ifi := range is { for _, ifi := range is {
var flags []string var flags []string
@ -131,7 +131,7 @@ func NetInterfaces() ([]NetInterfaceStat, error) {
flags = append(flags, "multicast") flags = append(flags, "multicast")
} }
r := NetInterfaceStat{ r := InterfaceStat{
Name: ifi.Name, Name: ifi.Name,
MTU: ifi.MTU, MTU: ifi.MTU,
HardwareAddr: ifi.HardwareAddr.String(), HardwareAddr: ifi.HardwareAddr.String(),
@ -139,9 +139,9 @@ func NetInterfaces() ([]NetInterfaceStat, error) {
} }
addrs, err := ifi.Addrs() addrs, err := ifi.Addrs()
if err == nil { if err == nil {
r.Addrs = make([]NetInterfaceAddr, 0, len(addrs)) r.Addrs = make([]InterfaceAddr, 0, len(addrs))
for _, addr := range addrs { for _, addr := range addrs {
r.Addrs = append(r.Addrs, NetInterfaceAddr{ r.Addrs = append(r.Addrs, InterfaceAddr{
Addr: addr.String(), Addr: addr.String(),
}) })
} }
@ -153,8 +153,8 @@ func NetInterfaces() ([]NetInterfaceStat, error) {
return ret, nil return ret, nil
} }
func getNetIOCountersAll(n []NetIOCountersStat) ([]NetIOCountersStat, error) { func getIOCountersAll(n []IOCountersStat) ([]IOCountersStat, error) {
r := NetIOCountersStat{ r := IOCountersStat{
Name: "all", Name: "all",
} }
for _, nic := range n { for _, nic := range n {
@ -168,38 +168,38 @@ func getNetIOCountersAll(n []NetIOCountersStat) ([]NetIOCountersStat, error) {
r.Dropout += nic.Dropout r.Dropout += nic.Dropout
} }
return []NetIOCountersStat{r}, nil return []IOCountersStat{r}, nil
} }
func parseNetLine(line string) (NetConnectionStat, error) { func parseNetLine(line string) (ConnectionStat, error) {
f := strings.Fields(line) f := strings.Fields(line)
if len(f) < 9 { if len(f) < 9 {
return NetConnectionStat{}, fmt.Errorf("wrong line,%s", line) return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
} }
pid, err := strconv.Atoi(f[1]) pid, err := strconv.Atoi(f[1])
if err != nil { if err != nil {
return NetConnectionStat{}, err return ConnectionStat{}, err
} }
fd, err := strconv.Atoi(strings.Trim(f[3], "u")) fd, err := strconv.Atoi(strings.Trim(f[3], "u"))
if err != nil { if err != nil {
return NetConnectionStat{}, fmt.Errorf("unknown fd, %s", f[3]) return ConnectionStat{}, fmt.Errorf("unknown fd, %s", f[3])
} }
netFamily, ok := constMap[f[4]] netFamily, ok := constMap[f[4]]
if !ok { if !ok {
return NetConnectionStat{}, fmt.Errorf("unknown family, %s", f[4]) return ConnectionStat{}, fmt.Errorf("unknown family, %s", f[4])
} }
netType, ok := constMap[f[7]] netType, ok := constMap[f[7]]
if !ok { if !ok {
return NetConnectionStat{}, fmt.Errorf("unknown type, %s", f[7]) return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[7])
} }
laddr, raddr, err := parseNetAddr(f[8]) laddr, raddr, err := parseNetAddr(f[8])
if err != nil { if err != nil {
return NetConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s", f[8]) return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s", f[8])
} }
n := NetConnectionStat{ n := ConnectionStat{
Fd: uint32(fd), Fd: uint32(fd),
Family: uint32(netFamily), Family: uint32(netFamily),
Type: uint32(netType), Type: uint32(netType),

@ -16,14 +16,18 @@ import (
// lo0 16384 <Link#1> 869107 0 169411755 869107 0 169411755 0 0 // lo0 16384 <Link#1> 869107 0 169411755 869107 0 169411755 0 0
// lo0 16384 ::1/128 ::1 869107 - 169411755 869107 - 169411755 - - // lo0 16384 ::1/128 ::1 869107 - 169411755 869107 - 169411755 - -
// lo0 16384 127 127.0.0.1 869107 - 169411755 869107 - 169411755 - - // lo0 16384 127 127.0.0.1 869107 - 169411755 869107 - 169411755 - -
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { func IOCounters(pernic bool) ([]IOCountersStat, error) {
out, err := exec.Command("/usr/sbin/netstat", "-ibdnW").Output() netstat, err := exec.LookPath("/usr/sbin/netstat")
if err != nil {
return nil, err
}
out, err := exec.Command(netstat, "-ibdnW").Output()
if err != nil { if err != nil {
return nil, err return nil, err
} }
lines := strings.Split(string(out), "\n") lines := strings.Split(string(out), "\n")
ret := make([]NetIOCountersStat, 0, len(lines)-1) ret := make([]IOCountersStat, 0, len(lines)-1)
exists := make([]string, 0, len(ret)) exists := make([]string, 0, len(ret))
for _, line := range lines { for _, line := range lines {
@ -70,7 +74,7 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
parsed = append(parsed, t) parsed = append(parsed, t)
} }
n := NetIOCountersStat{ n := IOCountersStat{
Name: values[0], Name: values[0],
PacketsRecv: parsed[0], PacketsRecv: parsed[0],
Errin: parsed[1], Errin: parsed[1],
@ -86,18 +90,18 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
} }
if pernic == false { if pernic == false {
return getNetIOCountersAll(ret) return getIOCountersAll(ret)
} }
return ret, nil return ret, nil
} }
// NetIOCountersByFile is an method which is added just a compatibility for linux. // NetIOCountersByFile is an method which is added just a compatibility for linux.
func NetIOCountersByFile(pernic bool, filename string) ([]NetIOCountersStat, error) { func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return NetIOCounters(pernic) return IOCounters(pernic)
} }
func NetFilterCounters() ([]NetFilterStat, error) { func FilterCounters() ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for darwin") return nil, errors.New("NetFilterCounters not implemented for darwin")
} }
@ -105,6 +109,6 @@ func NetFilterCounters() ([]NetFilterStat, error) {
// If protocols is empty then all protocols are returned, otherwise // If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned. // just the protocols in the list are returned.
// Not Implemented for Darwin // Not Implemented for Darwin
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) { func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for darwin") return nil, errors.New("NetProtoCounters not implemented for darwin")
} }

@ -11,14 +11,18 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { func IOCounters(pernic bool) ([]IOCountersStat, error) {
out, err := exec.Command("/usr/bin/netstat", "-ibdnW").Output() netstat, err := exec.LookPath("/usr/bin/netstat")
if err != nil {
return nil, err
}
out, err := exec.Command(netstat, "-ibdnW").Output()
if err != nil { if err != nil {
return nil, err return nil, err
} }
lines := strings.Split(string(out), "\n") lines := strings.Split(string(out), "\n")
ret := make([]NetIOCountersStat, 0, len(lines)-1) ret := make([]IOCountersStat, 0, len(lines)-1)
exists := make([]string, 0, len(ret)) exists := make([]string, 0, len(ret))
for _, line := range lines { for _, line := range lines {
@ -65,7 +69,7 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
parsed = append(parsed, t) parsed = append(parsed, t)
} }
n := NetIOCountersStat{ n := IOCountersStat{
Name: values[0], Name: values[0],
PacketsRecv: parsed[0], PacketsRecv: parsed[0],
Errin: parsed[1], Errin: parsed[1],
@ -80,18 +84,18 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
} }
if pernic == false { if pernic == false {
return getNetIOCountersAll(ret) return getIOCountersAll(ret)
} }
return ret, nil return ret, nil
} }
// NetIOCountersByFile is an method which is added just a compatibility for linux. // NetIOCountersByFile is an method which is added just a compatibility for linux.
func NetIOCountersByFile(pernic bool, filename string) ([]NetIOCountersStat, error) { func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return NetIOCounters(pernic) return IOCounters(pernic)
} }
func NetFilterCounters() ([]NetFilterStat, error) { func FilterCounters() ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for freebsd") return nil, errors.New("NetFilterCounters not implemented for freebsd")
} }
@ -99,6 +103,6 @@ func NetFilterCounters() ([]NetFilterStat, error) {
// If protocols is empty then all protocols are returned, otherwise // If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned. // just the protocols in the list are returned.
// Not Implemented for FreeBSD // Not Implemented for FreeBSD
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) { func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for freebsd") return nil, errors.New("NetProtoCounters not implemented for freebsd")
} }

@ -21,12 +21,12 @@ import (
// return only sum of all information (which name is 'all'). If true, // return only sum of all information (which name is 'all'). If true,
// every network interface installed on the system is returned // every network interface installed on the system is returned
// separately. // separately.
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { func IOCounters(pernic bool) ([]IOCountersStat, error) {
filename := common.HostProc("net/dev") filename := common.HostProc("net/dev")
return NetIOCountersByFile(pernic, filename) return IOCountersByFile(pernic, filename)
} }
func NetIOCountersByFile(pernic bool, filename string) ([]NetIOCountersStat, error) { func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
lines, err := common.ReadLines(filename) lines, err := common.ReadLines(filename)
if err != nil { if err != nil {
return nil, err return nil, err
@ -34,7 +34,7 @@ func NetIOCountersByFile(pernic bool, filename string) ([]NetIOCountersStat, err
statlen := len(lines) - 1 statlen := len(lines) - 1
ret := make([]NetIOCountersStat, 0, statlen) ret := make([]IOCountersStat, 0, statlen)
for _, line := range lines[2:] { for _, line := range lines[2:] {
parts := strings.SplitN(line, ":", 2) parts := strings.SplitN(line, ":", 2)
@ -80,7 +80,7 @@ func NetIOCountersByFile(pernic bool, filename string) ([]NetIOCountersStat, err
return ret, err return ret, err
} }
nic := NetIOCountersStat{ nic := IOCountersStat{
Name: interfaceName, Name: interfaceName,
BytesRecv: bytesRecv, BytesRecv: bytesRecv,
PacketsRecv: packetsRecv, PacketsRecv: packetsRecv,
@ -95,7 +95,7 @@ func NetIOCountersByFile(pernic bool, filename string) ([]NetIOCountersStat, err
} }
if pernic == false { if pernic == false {
return getNetIOCountersAll(ret) return getIOCountersAll(ret)
} }
return ret, nil return ret, nil
@ -115,12 +115,12 @@ var netProtocols = []string{
// just the protocols in the list are returned. // just the protocols in the list are returned.
// Available protocols: // Available protocols:
// ip,icmp,icmpmsg,tcp,udp,udplite // ip,icmp,icmpmsg,tcp,udp,udplite
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) { func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
if len(protocols) == 0 { if len(protocols) == 0 {
protocols = netProtocols protocols = netProtocols
} }
stats := make([]NetProtoCountersStat, 0, len(protocols)) stats := make([]ProtoCountersStat, 0, len(protocols))
protos := make(map[string]bool, len(protocols)) protos := make(map[string]bool, len(protocols))
for _, p := range protocols { for _, p := range protocols {
protos[p] = true protos[p] = true
@ -155,7 +155,7 @@ func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) {
if len(statNames) != len(statValues) { if len(statNames) != len(statValues) {
return nil, errors.New(filename + " is not fomatted correctly, expected same number of columns.") return nil, errors.New(filename + " is not fomatted correctly, expected same number of columns.")
} }
stat := NetProtoCountersStat{ stat := ProtoCountersStat{
Protocol: proto, Protocol: proto,
Stats: make(map[string]int64, len(statNames)), Stats: make(map[string]int64, len(statNames)),
} }
@ -174,23 +174,23 @@ func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) {
// NetFilterCounters returns iptables conntrack statistics // NetFilterCounters returns iptables conntrack statistics
// the currently in use conntrack count and the max. // the currently in use conntrack count and the max.
// If the file does not exist or is invalid it will return nil. // If the file does not exist or is invalid it will return nil.
func NetFilterCounters() ([]NetFilterStat, error) { func FilterCounters() ([]FilterStat, error) {
countfile := common.HostProc("sys/net/netfilter/nf_conntrack_count") countfile := common.HostProc("sys/net/netfilter/nf_conntrackCount")
maxfile := common.HostProc("sys/net/netfilter/nf_conntrack_max") maxfile := common.HostProc("sys/net/netfilter/nf_conntrackMax")
count, err := common.ReadInts(countfile) count, err := common.ReadInts(countfile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
stats := make([]NetFilterStat, 0, 1) stats := make([]FilterStat, 0, 1)
max, err := common.ReadInts(maxfile) max, err := common.ReadInts(maxfile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
payload := NetFilterStat{ payload := FilterStat{
ConnTrackCount: count[0], ConnTrackCount: count[0],
ConnTrackMax: max[0], ConnTrackMax: max[0],
} }
@ -277,12 +277,12 @@ type connTmp struct {
} }
// Return a list of network connections opened. // Return a list of network connections opened.
func NetConnections(kind string) ([]NetConnectionStat, error) { func Connections(kind string) ([]ConnectionStat, error) {
return NetConnectionsPid(kind, 0) return ConnectionsPid(kind, 0)
} }
// Return a list of network connections opened by a process. // Return a list of network connections opened by a process.
func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) { func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
tmap, ok := netConnectionKindMap[kind] tmap, ok := netConnectionKindMap[kind]
if !ok { if !ok {
return nil, fmt.Errorf("invalid kind, %s", kind) return nil, fmt.Errorf("invalid kind, %s", kind)
@ -296,7 +296,7 @@ func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) {
inodes, err = getProcInodes(root, pid) inodes, err = getProcInodes(root, pid)
if len(inodes) == 0 { if len(inodes) == 0 {
// no connection for the pid // no connection for the pid
return []NetConnectionStat{}, nil return []ConnectionStat{}, nil
} }
} }
if err != nil { if err != nil {
@ -304,7 +304,7 @@ func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) {
} }
dupCheckMap := make(map[string]bool) dupCheckMap := make(map[string]bool)
var ret []NetConnectionStat var ret []ConnectionStat
for _, t := range tmap { for _, t := range tmap {
var path string var path string
@ -322,7 +322,7 @@ func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) {
return nil, err return nil, err
} }
for _, c := range ls { for _, c := range ls {
conn := NetConnectionStat{ conn := ConnectionStat{
Fd: c.fd, Fd: c.fd,
Family: c.family, Family: c.family,
Type: c.sockType, Type: c.sockType,

@ -19,18 +19,18 @@ func TestAddrString(t *testing.T) {
} }
func TestNetIOCountersStatString(t *testing.T) { func TestNetIOCountersStatString(t *testing.T) {
v := NetIOCountersStat{ v := IOCountersStat{
Name: "test", Name: "test",
BytesSent: 100, BytesSent: 100,
} }
e := `{"name":"test","bytes_sent":100,"bytes_recv":0,"packets_sent":0,"packets_recv":0,"errin":0,"errout":0,"dropin":0,"dropout":0}` e := `{"name":"test","bytesSent":100,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0}`
if e != fmt.Sprintf("%v", v) { if e != fmt.Sprintf("%v", v) {
t.Errorf("NetIOCountersStat string is invalid: %v", v) t.Errorf("NetIOCountersStat string is invalid: %v", v)
} }
} }
func TestNetProtoCountersStatString(t *testing.T) { func TestNetProtoCountersStatString(t *testing.T) {
v := NetProtoCountersStat{ v := ProtoCountersStat{
Protocol: "tcp", Protocol: "tcp",
Stats: map[string]int64{ Stats: map[string]int64{
"MaxConn": -1, "MaxConn": -1,
@ -46,7 +46,7 @@ func TestNetProtoCountersStatString(t *testing.T) {
} }
func TestNetConnectionStatString(t *testing.T) { func TestNetConnectionStatString(t *testing.T) {
v := NetConnectionStat{ v := ConnectionStat{
Fd: 10, Fd: 10,
Family: 10, Family: 10,
Type: 10, Type: 10,
@ -59,8 +59,8 @@ func TestNetConnectionStatString(t *testing.T) {
} }
func TestNetIOCountersAll(t *testing.T) { func TestNetIOCountersAll(t *testing.T) {
v, err := NetIOCounters(false) v, err := IOCounters(false)
per, err := NetIOCounters(true) per, err := IOCounters(true)
if err != nil { if err != nil {
t.Errorf("Could not get NetIOCounters: %v", err) t.Errorf("Could not get NetIOCounters: %v", err)
} }
@ -80,7 +80,7 @@ func TestNetIOCountersAll(t *testing.T) {
} }
func TestNetIOCountersPerNic(t *testing.T) { func TestNetIOCountersPerNic(t *testing.T) {
v, err := NetIOCounters(true) v, err := IOCounters(true)
if err != nil { if err != nil {
t.Errorf("Could not get NetIOCounters: %v", err) t.Errorf("Could not get NetIOCounters: %v", err)
} }
@ -95,20 +95,20 @@ func TestNetIOCountersPerNic(t *testing.T) {
} }
func TestGetNetIOCountersAll(t *testing.T) { func TestGetNetIOCountersAll(t *testing.T) {
n := []NetIOCountersStat{ n := []IOCountersStat{
NetIOCountersStat{ IOCountersStat{
Name: "a", Name: "a",
BytesRecv: 10, BytesRecv: 10,
PacketsRecv: 10, PacketsRecv: 10,
}, },
NetIOCountersStat{ IOCountersStat{
Name: "b", Name: "b",
BytesRecv: 10, BytesRecv: 10,
PacketsRecv: 10, PacketsRecv: 10,
Errin: 10, Errin: 10,
}, },
} }
ret, err := getNetIOCountersAll(n) ret, err := getIOCountersAll(n)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -127,7 +127,7 @@ func TestGetNetIOCountersAll(t *testing.T) {
} }
func TestNetInterfaces(t *testing.T) { func TestNetInterfaces(t *testing.T) {
v, err := NetInterfaces() v, err := Interfaces()
if err != nil { if err != nil {
t.Errorf("Could not get NetInterfaceStat: %v", err) t.Errorf("Could not get NetInterfaceStat: %v", err)
} }
@ -142,7 +142,7 @@ func TestNetInterfaces(t *testing.T) {
} }
func TestNetProtoCountersStatsAll(t *testing.T) { func TestNetProtoCountersStatsAll(t *testing.T) {
v, err := NetProtoCounters(nil) v, err := ProtoCounters(nil)
if err != nil { if err != nil {
t.Fatalf("Could not get NetProtoCounters: %v", err) t.Fatalf("Could not get NetProtoCounters: %v", err)
} }
@ -160,7 +160,7 @@ func TestNetProtoCountersStatsAll(t *testing.T) {
} }
func TestNetProtoCountersStats(t *testing.T) { func TestNetProtoCountersStats(t *testing.T) {
v, err := NetProtoCounters([]string{"tcp", "ip"}) v, err := ProtoCounters([]string{"tcp", "ip"})
if err != nil { if err != nil {
t.Fatalf("Could not get NetProtoCounters: %v", err) t.Fatalf("Could not get NetProtoCounters: %v", err)
} }
@ -185,7 +185,7 @@ func TestNetConnections(t *testing.T) {
return return
} }
v, err := NetConnections("inet") v, err := Connections("inet")
if err != nil { if err != nil {
t.Errorf("could not get NetConnections: %v", err) t.Errorf("could not get NetConnections: %v", err)
} }
@ -207,12 +207,12 @@ func TestNetFilterCounters(t *testing.T) {
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
// some test environment has not the path. // some test environment has not the path.
if !common.PathExists("/proc/sys/net/netfilter/nf_conntrack_count") { if !common.PathExists("/proc/sys/net/netfilter/nf_conntrackCount") {
t.SkipNow() t.SkipNow()
} }
} }
v, err := NetFilterCounters() v, err := FilterCounters()
if err != nil { if err != nil {
t.Errorf("could not get NetConnections: %v", err) t.Errorf("could not get NetConnections: %v", err)
} }
@ -221,7 +221,7 @@ func TestNetFilterCounters(t *testing.T) {
} }
for _, vv := range v { for _, vv := range v {
if vv.ConnTrackMax == 0 { if vv.ConnTrackMax == 0 {
t.Errorf("nf_conntrack_max needs to be greater than zero: %v", vv) t.Errorf("nf_conntrackMax needs to be greater than zero: %v", vv)
} }
} }

@ -9,13 +9,13 @@ import (
) )
// Return a list of network connections opened. // Return a list of network connections opened.
func NetConnections(kind string) ([]NetConnectionStat, error) { func Connections(kind string) ([]ConnectionStat, error) {
return NetConnectionsPid(kind, 0) return ConnectionsPid(kind, 0)
} }
// Return a list of network connections opened by a process. // Return a list of network connections opened by a process.
func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) { func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
var ret []NetConnectionStat var ret []ConnectionStat
args := []string{"-i"} args := []string{"-i"}
switch strings.ToLower(kind) { switch strings.ToLower(kind) {
@ -44,7 +44,7 @@ func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) {
case "udp6": case "udp6":
args = append(args, "6udp") args = append(args, "6udp")
case "unix": case "unix":
return ret, common.NotImplementedError return ret, common.ErrNotImplementedError
} }
r, err := common.CallLsof(invoke, pid, args...) r, err := common.CallLsof(invoke, pid, args...)

@ -14,8 +14,8 @@ import (
var ( var (
modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll") modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
procGetExtendedTcpTable = modiphlpapi.NewProc("GetExtendedTcpTable") procGetExtendedTCPTable = modiphlpapi.NewProc("GetExtendedTcpTable")
procGetExtendedUdpTable = modiphlpapi.NewProc("GetExtendedUdpTable") procGetExtendedUDPTable = modiphlpapi.NewProc("GetExtendedUdpTable")
) )
const ( const (
@ -30,7 +30,7 @@ const (
TCPTableOwnerModuleAll TCPTableOwnerModuleAll
) )
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { func IOCounters(pernic bool) ([]IOCountersStat, error) {
ifs, err := net.Interfaces() ifs, err := net.Interfaces()
if err != nil { if err != nil {
return nil, err return nil, err
@ -40,13 +40,13 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
var ret []NetIOCountersStat var ret []IOCountersStat
for _, ifi := range ifs { for _, ifi := range ifs {
name := ifi.Name name := ifi.Name
for ; ai != nil; ai = ai.Next { for ; ai != nil; ai = ai.Next {
name = common.BytePtrToString(&ai.Description[0]) name = common.BytePtrToString(&ai.Description[0])
c := NetIOCountersStat{ c := IOCountersStat{
Name: name, Name: name,
} }
@ -69,21 +69,21 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
} }
if pernic == false { if pernic == false {
return getNetIOCountersAll(ret) return getIOCountersAll(ret)
} }
return ret, nil return ret, nil
} }
// NetIOCountersByFile is an method which is added just a compatibility for linux. // NetIOCountersByFile is an method which is added just a compatibility for linux.
func NetIOCountersByFile(pernic bool, filename string) ([]NetIOCountersStat, error) { func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return NetIOCounters(pernic) return IOCounters(pernic)
} }
// Return a list of network connections opened by a process // Return a list of network connections opened by a process
func NetConnections(kind string) ([]NetConnectionStat, error) { func Connections(kind string) ([]ConnectionStat, error) {
var ret []NetConnectionStat var ret []ConnectionStat
return ret, common.NotImplementedError return ret, common.ErrNotImplementedError
} }
// borrowed from src/pkg/net/interface_windows.go // borrowed from src/pkg/net/interface_windows.go
@ -103,7 +103,7 @@ func getAdapterList() (*syscall.IpAdapterInfo, error) {
return a, nil return a, nil
} }
func NetFilterCounters() ([]NetFilterStat, error) { func FilterCounters() ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for windows") return nil, errors.New("NetFilterCounters not implemented for windows")
} }
@ -111,6 +111,6 @@ func NetFilterCounters() ([]NetFilterStat, error) {
// If protocols is empty then all protocols are returned, otherwise // If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned. // just the protocols in the list are returned.
// Not Implemented for Windows // Not Implemented for Windows
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) { func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for windows") return nil, errors.New("NetProtoCounters not implemented for windows")
} }

@ -26,7 +26,7 @@ type Process struct {
numThreads int32 numThreads int32
memInfo *MemoryInfoStat memInfo *MemoryInfoStat
lastCPUTimes *cpu.CPUTimesStat lastCPUTimes *cpu.TimesStat
lastCPUTime time.Time lastCPUTime time.Time
} }
@ -48,10 +48,10 @@ type RlimitStat struct {
} }
type IOCountersStat struct { type IOCountersStat struct {
ReadCount uint64 `json:"read_count"` ReadCount uint64 `json:"readCount"`
WriteCount uint64 `json:"write_count"` WriteCount uint64 `json:"writeCount"`
ReadBytes uint64 `json:"read_bytes"` ReadBytes uint64 `json:"readBytes"`
WriteBytes uint64 `json:"write_bytes"` WriteBytes uint64 `json:"writeBytes"`
} }
type NumCtxSwitchesStat struct { type NumCtxSwitchesStat struct {
@ -106,8 +106,8 @@ func PidExists(pid int32) (bool, error) {
// If interval is 0, return difference from last call(non-blocking). // If interval is 0, return difference from last call(non-blocking).
// If interval > 0, wait interval sec and return diffrence between start and end. // If interval > 0, wait interval sec and return diffrence between start and end.
func (p *Process) CPUPercent(interval time.Duration) (float64, error) { func (p *Process) Percent(interval time.Duration) (float64, error) {
cpuTimes, err := p.CPUTimes() cpuTimes, err := p.Times()
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -117,7 +117,7 @@ func (p *Process) CPUPercent(interval time.Duration) (float64, error) {
p.lastCPUTimes = cpuTimes p.lastCPUTimes = cpuTimes
p.lastCPUTime = now p.lastCPUTime = now
time.Sleep(interval) time.Sleep(interval)
cpuTimes, err = p.CPUTimes() cpuTimes, err = p.Times()
now = time.Now() now = time.Now()
if err != nil { if err != nil {
return 0, err return 0, err
@ -139,7 +139,7 @@ func (p *Process) CPUPercent(interval time.Duration) (float64, error) {
return ret, nil return ret, nil
} }
func calculatePercent(t1, t2 *cpu.CPUTimesStat, delta float64, numcpu int) float64 { func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64 {
if delta == 0 { if delta == 0 {
return 0 return 0
} }

@ -79,7 +79,7 @@ func (p *Process) Name() (string, error) {
return common.IntToString(k.Proc.P_comm[:]), nil return common.IntToString(k.Proc.P_comm[:]), nil
} }
func (p *Process) Exe() (string, error) { func (p *Process) Exe() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
// Cmdline returns the command line arguments of the process as a string with // Cmdline returns the command line arguments of the process as a string with
@ -105,10 +105,10 @@ func (p *Process) CmdlineSlice() ([]string, error) {
return r[0], err return r[0], err
} }
func (p *Process) CreateTime() (int64, error) { func (p *Process) CreateTime() (int64, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
rr, err := common.CallLsof(invoke, p.Pid, "-FR") rr, err := common.CallLsof(invoke, p.Pid, "-FR")
@ -143,7 +143,7 @@ func (p *Process) Uids() ([]int32, error) {
} }
// See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html // See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html
userEffectiveUID := int32(k.Eproc.Ucred.Uid) userEffectiveUID := int32(k.Eproc.Ucred.UID)
return []int32{userEffectiveUID}, nil return []int32{userEffectiveUID}, nil
} }
@ -159,7 +159,7 @@ func (p *Process) Gids() ([]int32, error) {
return gids, nil return gids, nil
} }
func (p *Process) Terminal() (string, error) { func (p *Process) Terminal() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
/* /*
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
@ -183,20 +183,20 @@ func (p *Process) Nice() (int32, error) {
return int32(k.Proc.P_nice), nil return int32(k.Proc.P_nice), nil
} }
func (p *Process) IOnice() (int32, error) { func (p *Process) IOnice() (int32, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Rlimit() ([]RlimitStat, error) { func (p *Process) Rlimit() ([]RlimitStat, error) {
var rlimit []RlimitStat var rlimit []RlimitStat
return rlimit, common.NotImplementedError return rlimit, common.ErrNotImplementedError
} }
func (p *Process) IOCounters() (*IOCountersStat, error) { func (p *Process) IOCounters() (*IOCountersStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) { func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumFDs() (int32, error) { func (p *Process) NumFDs() (int32, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) NumThreads() (int32, error) { func (p *Process) NumThreads() (int32, error) {
r, err := callPs("utime,stime", p.Pid, true) r, err := callPs("utime,stime", p.Pid, true)
@ -207,10 +207,10 @@ func (p *Process) NumThreads() (int32, error) {
} }
func (p *Process) Threads() (map[string]string, error) { func (p *Process) Threads() (map[string]string, error) {
ret := make(map[string]string, 0) ret := make(map[string]string, 0)
return ret, common.NotImplementedError return ret, common.ErrNotImplementedError
} }
func convertCpuTimes(s string) (ret float64, err error) { func convertCPUTimes(s string) (ret float64, err error) {
var t int var t int
var _tmp string var _tmp string
if strings.Contains(s, ":") { if strings.Contains(s, ":") {
@ -235,23 +235,23 @@ func convertCpuTimes(s string) (ret float64, err error) {
t += h t += h
return float64(t) / ClockTicks, nil return float64(t) / ClockTicks, nil
} }
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) { func (p *Process) Times() (*cpu.TimesStat, error) {
r, err := callPs("utime,stime", p.Pid, false) r, err := callPs("utime,stime", p.Pid, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
utime, err := convertCpuTimes(r[0][0]) utime, err := convertCPUTimes(r[0][0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
stime, err := convertCpuTimes(r[0][1]) stime, err := convertCPUTimes(r[0][1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret := &cpu.CPUTimesStat{ ret := &cpu.TimesStat{
CPU: "cpu", CPU: "cpu",
User: utime, User: utime,
System: stime, System: stime,
@ -259,7 +259,7 @@ func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
return ret, nil return ret, nil
} }
func (p *Process) CPUAffinity() ([]int32, error) { func (p *Process) CPUAffinity() ([]int32, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
r, err := callPs("rss,vsize,pagein", p.Pid, false) r, err := callPs("rss,vsize,pagein", p.Pid, false)
@ -288,7 +288,7 @@ func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return ret, nil return ret, nil
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) { func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Children() ([]*Process, error) { func (p *Process) Children() ([]*Process, error) {
@ -308,28 +308,23 @@ func (p *Process) Children() ([]*Process, error) {
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) { func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Connections() ([]net.NetConnectionStat, error) { func (p *Process) Connections() ([]net.ConnectionStat, error) {
return net.NetConnectionsPid("all", p.Pid) return net.ConnectionsPid("all", p.Pid)
} }
func (p *Process) NetIOCounters(pernic bool) ([]net.NetIOCountersStat, error) { func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) { func (p *Process) IsRunning() (bool, error) {
return true, common.NotImplementedError return true, common.ErrNotImplementedError
} }
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat var ret []MemoryMapsStat
return &ret, common.NotImplementedError return &ret, common.ErrNotImplementedError
}
func copyParams(k *KinfoProc, p *Process) error {
return nil
} }
func processes() ([]Process, error) { func processes() ([]Process, error) {
@ -364,8 +359,6 @@ func processes() ([]Process, error) {
if err != nil { if err != nil {
continue continue
} }
copyParams(&k, p)
results = append(results, *p) results = append(results, *p)
} }

@ -101,7 +101,7 @@ type ucred struct {
type Uucred struct { type Uucred struct {
Ref int32 Ref int32
Uid uint32 UID uint32
Ngroups int16 Ngroups int16
Pad_cgo_0 [2]byte Pad_cgo_0 [2]byte
Groups [16]uint32 Groups [16]uint32
@ -197,7 +197,7 @@ type Au_session struct {
} }
type Posix_cred struct { type Posix_cred struct {
Uid uint32 UID uint32
Ruid uint32 Ruid uint32
Svuid uint32 Svuid uint32
Ngroups int16 Ngroups int16

@ -51,7 +51,7 @@ func (p *Process) Name() (string, error) {
return common.IntToString(k.Comm[:]), nil return common.IntToString(k.Comm[:]), nil
} }
func (p *Process) Exe() (string, error) { func (p *Process) Exe() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Cmdline() (string, error) { func (p *Process) Cmdline() (string, error) {
@ -91,13 +91,13 @@ func (p *Process) CmdlineSlice() ([]string, error) {
return strParts, nil return strParts, nil
} }
func (p *Process) CreateTime() (int64, error) { func (p *Process) CreateTime() (int64, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
return p, common.NotImplementedError return p, common.ErrNotImplementedError
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -170,11 +170,11 @@ func (p *Process) Nice() (int32, error) {
return int32(k.Nice), nil return int32(k.Nice), nil
} }
func (p *Process) IOnice() (int32, error) { func (p *Process) IOnice() (int32, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Rlimit() ([]RlimitStat, error) { func (p *Process) Rlimit() ([]RlimitStat, error) {
var rlimit []RlimitStat var rlimit []RlimitStat
return rlimit, common.NotImplementedError return rlimit, common.ErrNotImplementedError
} }
func (p *Process) IOCounters() (*IOCountersStat, error) { func (p *Process) IOCounters() (*IOCountersStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -187,10 +187,10 @@ func (p *Process) IOCounters() (*IOCountersStat, error) {
}, nil }, nil
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) { func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumFDs() (int32, error) { func (p *Process) NumFDs() (int32, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) NumThreads() (int32, error) { func (p *Process) NumThreads() (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -202,21 +202,21 @@ func (p *Process) NumThreads() (int32, error) {
} }
func (p *Process) Threads() (map[string]string, error) { func (p *Process) Threads() (map[string]string, error) {
ret := make(map[string]string, 0) ret := make(map[string]string, 0)
return ret, common.NotImplementedError return ret, common.ErrNotImplementedError
} }
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) { func (p *Process) Times() (*cpu.TimesStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &cpu.CPUTimesStat{ return &cpu.TimesStat{
CPU: "cpu", CPU: "cpu",
User: float64(k.Rusage.Utime.Sec) + float64(k.Rusage.Utime.Usec)/1000000, User: float64(k.Rusage.Utime.Sec) + float64(k.Rusage.Utime.Usec)/1000000,
System: float64(k.Rusage.Stime.Sec) + float64(k.Rusage.Stime.Usec)/1000000, System: float64(k.Rusage.Stime.Sec) + float64(k.Rusage.Stime.Usec)/1000000,
}, nil }, nil
} }
func (p *Process) CPUAffinity() ([]int32, error) { func (p *Process) CPUAffinity() ([]int32, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -235,7 +235,7 @@ func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
}, nil }, nil
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) { func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Children() ([]*Process, error) { func (p *Process) Children() ([]*Process, error) {
@ -255,23 +255,23 @@ func (p *Process) Children() ([]*Process, error) {
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) { func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Connections() ([]net.NetConnectionStat, error) { func (p *Process) Connections() ([]net.ConnectionStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NetIOCounters(pernic bool) ([]net.NetIOCountersStat, error) { func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) { func (p *Process) IsRunning() (bool, error) {
return true, common.NotImplementedError return true, common.ErrNotImplementedError
} }
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat var ret []MemoryMapsStat
return &ret, common.NotImplementedError return &ret, common.ErrNotImplementedError
} }
func processes() ([]Process, error) { func processes() ([]Process, error) {

@ -48,10 +48,10 @@ type MemoryMapsStat struct {
Rss uint64 `json:"rss"` Rss uint64 `json:"rss"`
Size uint64 `json:"size"` Size uint64 `json:"size"`
Pss uint64 `json:"pss"` Pss uint64 `json:"pss"`
SharedClean uint64 `json:"shared_clean"` SharedClean uint64 `json:"sharedClean"`
SharedDirty uint64 `json:"shared_dirty"` SharedDirty uint64 `json:"sharedDirty"`
PrivateClean uint64 `json:"private_clean"` PrivateClean uint64 `json:"privateClean"`
PrivateDirty uint64 `json:"private_dirty"` PrivateDirty uint64 `json:"privateDirty"`
Referenced uint64 `json:"referenced"` Referenced uint64 `json:"referenced"`
Anonymous uint64 `json:"anonymous"` Anonymous uint64 `json:"anonymous"`
Swap uint64 `json:"swap"` Swap uint64 `json:"swap"`
@ -167,10 +167,10 @@ func (p *Process) Nice() (int32, error) {
return nice, nil return nice, nil
} }
func (p *Process) IOnice() (int32, error) { func (p *Process) IOnice() (int32, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Rlimit() ([]RlimitStat, error) { func (p *Process) Rlimit() ([]RlimitStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IOCounters() (*IOCountersStat, error) { func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.fillFromIO() return p.fillFromIO()
@ -197,7 +197,7 @@ func (p *Process) Threads() (map[string]string, error) {
ret := make(map[string]string, 0) ret := make(map[string]string, 0)
return ret, nil return ret, nil
} }
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) { func (p *Process) Times() (*cpu.TimesStat, error) {
_, _, cpuTimes, _, _, err := p.fillFromStat() _, _, cpuTimes, _, _, err := p.fillFromStat()
if err != nil { if err != nil {
return nil, err return nil, err
@ -205,7 +205,7 @@ func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
return cpuTimes, nil return cpuTimes, nil
} }
func (p *Process) CPUAffinity() ([]int32, error) { func (p *Process) CPUAffinity() ([]int32, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
meminfo, _, err := p.fillFromStatm() meminfo, _, err := p.fillFromStatm()
@ -254,17 +254,17 @@ func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return ret, nil return ret, nil
} }
func (p *Process) Connections() ([]net.NetConnectionStat, error) { func (p *Process) Connections() ([]net.ConnectionStat, error) {
return net.NetConnectionsPid("all", p.Pid) return net.ConnectionsPid("all", p.Pid)
} }
func (p *Process) NetIOCounters(pernic bool) ([]net.NetIOCountersStat, error) { func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
filename := common.HostProc(strconv.Itoa(int(p.Pid)), "net/dev") filename := common.HostProc(strconv.Itoa(int(p.Pid)), "net/dev")
return net.NetIOCountersByFile(pernic, filename) return net.IOCountersByFile(pernic, filename)
} }
func (p *Process) IsRunning() (bool, error) { func (p *Process) IsRunning() (bool, error) {
return true, common.NotImplementedError return true, common.ErrNotImplementedError
} }
// MemoryMaps get memory maps from /proc/(pid)/smaps // MemoryMaps get memory maps from /proc/(pid)/smaps
@ -361,7 +361,7 @@ func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) {
fnames, err := d.Readdirnames(-1) fnames, err := d.Readdirnames(-1)
numFDs := int32(len(fnames)) numFDs := int32(len(fnames))
openfiles := make([]*OpenFilesStat, 0) var openfiles []*OpenFilesStat
for _, fd := range fnames { for _, fd := range fnames {
fpath := filepath.Join(statPath, fd) fpath := filepath.Join(statPath, fd)
filepath, err := os.Readlink(fpath) filepath, err := os.Readlink(fpath)
@ -473,9 +473,9 @@ func (p *Process) fillFromIO() (*IOCountersStat, error) {
ret.ReadCount = t ret.ReadCount = t
case "syscw": case "syscw":
ret.WriteCount = t ret.WriteCount = t
case "read_bytes": case "readBytes":
ret.ReadBytes = t ret.ReadBytes = t
case "write_bytes": case "writeBytes":
ret.WriteBytes = t ret.WriteBytes = t
} }
} }
@ -556,10 +556,7 @@ func (p *Process) fillFromStatus() error {
case "Name": case "Name":
p.name = strings.Trim(value, " \t") p.name = strings.Trim(value, " \t")
case "State": case "State":
// get between "(" and ")" p.status = value[0:1]
s := strings.Index(value, "(") + 1
e := strings.Index(value, ")")
p.status = value[s:e]
case "Uid": case "Uid":
p.uids = make([]int32, 0, 4) p.uids = make([]int32, 0, 4)
for _, i := range strings.Split(value, "\t") { for _, i := range strings.Split(value, "\t") {
@ -623,7 +620,7 @@ func (p *Process) fillFromStatus() error {
return nil return nil
} }
func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32, error) { func (p *Process) fillFromStat() (string, int32, *cpu.TimesStat, int64, int32, error) {
pid := p.Pid pid := p.Pid
statPath := common.HostProc(strconv.Itoa(int(pid)), "stat") statPath := common.HostProc(strconv.Itoa(int(pid)), "stat")
contents, err := ioutil.ReadFile(statPath) contents, err := ioutil.ReadFile(statPath)
@ -661,7 +658,7 @@ func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32
return "", 0, nil, 0, 0, err return "", 0, nil, 0, 0, err
} }
cpuTimes := &cpu.CPUTimesStat{ cpuTimes := &cpu.TimesStat{
CPU: "cpu", CPU: "cpu",
User: float64(utime / ClockTicks), User: float64(utime / ClockTicks),
System: float64(stime / ClockTicks), System: float64(stime / ClockTicks),

@ -64,9 +64,13 @@ func (p *Process) SendSignal(sig syscall.Signal) error {
sigAsStr = "KILL" sigAsStr = "KILL"
} }
cmd := exec.Command("kill", "-s", sigAsStr, strconv.Itoa(int(p.Pid))) kill, err := exec.LookPath("kill")
if err != nil {
return err
}
cmd := exec.Command(kill, "-s", sigAsStr, strconv.Itoa(int(p.Pid)))
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err := cmd.Run() err = cmd.Run()
if err != nil { if err != nil {
return err return err
} }

@ -152,7 +152,7 @@ func Test_Process_Status(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("geting status error %v", err) t.Errorf("geting status error %v", err)
} }
if !strings.HasPrefix(v, "S") && v != "running" && v != "sleeping" { if v != "R" && v != "S" {
t.Errorf("could not get state %v", v) t.Errorf("could not get state %v", v)
} }
} }
@ -244,13 +244,13 @@ func Test_Process_Exe(t *testing.T) {
func Test_Process_CpuPercent(t *testing.T) { func Test_Process_CpuPercent(t *testing.T) {
p := testGetProcess() p := testGetProcess()
percent, err := p.CPUPercent(0) percent, err := p.Percent(0)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
duration := time.Duration(1000) * time.Microsecond duration := time.Duration(1000) * time.Microsecond
time.Sleep(duration) time.Sleep(duration)
percent, err = p.CPUPercent(0) percent, err = p.Percent(0)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
@ -268,7 +268,7 @@ func Test_Process_CpuPercentLoop(t *testing.T) {
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
duration := time.Duration(100) * time.Microsecond duration := time.Duration(100) * time.Microsecond
percent, err := p.CPUPercent(duration) percent, err := p.Percent(duration)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
@ -360,7 +360,7 @@ func Test_CPUTimes(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
spinSeconds := 0.2 spinSeconds := 0.2
cpuTimes0, err := process.CPUTimes() cpuTimes0, err := process.Times()
assert.Nil(t, err) assert.Nil(t, err)
// Spin for a duration of spinSeconds // Spin for a duration of spinSeconds
@ -371,7 +371,7 @@ func Test_CPUTimes(t *testing.T) {
// This block intentionally left blank // This block intentionally left blank
} }
cpuTimes1, err := process.CPUTimes() cpuTimes1, err := process.Times()
assert.Nil(t, err) assert.Nil(t, err)
if cpuTimes0 == nil || cpuTimes1 == nil { if cpuTimes0 == nil || cpuTimes1 == nil {

@ -51,7 +51,7 @@ type Win32_Process struct {
CommandLine *string CommandLine *string
Priority uint32 Priority uint32
CreationDate *time.Time CreationDate *time.Time
ProcessId uint32 ProcessID uint32
ThreadCount uint32 ThreadCount uint32
/* /*
@ -71,7 +71,7 @@ type Win32_Process struct {
OtherTransferCount uint64 OtherTransferCount uint64
PageFaults uint32 PageFaults uint32
PageFileUsage uint32 PageFileUsage uint32
ParentProcessId uint32 ParentProcessID uint32
PeakPageFileUsage uint32 PeakPageFileUsage uint32
PeakVirtualSize uint64 PeakVirtualSize uint64
PeakWorkingSetSize uint32 PeakWorkingSetSize uint32
@ -167,28 +167,28 @@ func (p *Process) CreateTime() (int64, error) {
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
return p, common.NotImplementedError return p, common.ErrNotImplementedError
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Username() (string, error) { func (p *Process) Username() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Uids() ([]int32, error) { func (p *Process) Uids() ([]int32, error) {
var uids []int32 var uids []int32
return uids, common.NotImplementedError return uids, common.ErrNotImplementedError
} }
func (p *Process) Gids() ([]int32, error) { func (p *Process) Gids() ([]int32, error) {
var gids []int32 var gids []int32
return gids, common.NotImplementedError return gids, common.ErrNotImplementedError
} }
func (p *Process) Terminal() (string, error) { func (p *Process) Terminal() (string, error) {
return "", common.NotImplementedError return "", common.ErrNotImplementedError
} }
// Nice returnes priority in Windows // Nice returnes priority in Windows
@ -200,21 +200,21 @@ func (p *Process) Nice() (int32, error) {
return int32(dst[0].Priority), nil return int32(dst[0].Priority), nil
} }
func (p *Process) IOnice() (int32, error) { func (p *Process) IOnice() (int32, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Rlimit() ([]RlimitStat, error) { func (p *Process) Rlimit() ([]RlimitStat, error) {
var rlimit []RlimitStat var rlimit []RlimitStat
return rlimit, common.NotImplementedError return rlimit, common.ErrNotImplementedError
} }
func (p *Process) IOCounters() (*IOCountersStat, error) { func (p *Process) IOCounters() (*IOCountersStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) { func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumFDs() (int32, error) { func (p *Process) NumFDs() (int32, error) {
return 0, common.NotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) NumThreads() (int32, error) { func (p *Process) NumThreads() (int32, error) {
dst, err := GetWin32Proc(p.Pid) dst, err := GetWin32Proc(p.Pid)
@ -225,44 +225,44 @@ func (p *Process) NumThreads() (int32, error) {
} }
func (p *Process) Threads() (map[string]string, error) { func (p *Process) Threads() (map[string]string, error) {
ret := make(map[string]string, 0) ret := make(map[string]string, 0)
return ret, common.NotImplementedError return ret, common.ErrNotImplementedError
} }
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) { func (p *Process) Times() (*cpu.TimesStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) CPUAffinity() ([]int32, error) { func (p *Process) CPUAffinity() ([]int32, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) { func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Children() ([]*Process, error) { func (p *Process) Children() ([]*Process, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) { func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Connections() ([]net.NetConnectionStat, error) { func (p *Process) Connections() ([]net.ConnectionStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NetIOCounters(pernic bool) ([]net.NetIOCountersStat, error) { func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return nil, common.NotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) { func (p *Process) IsRunning() (bool, error) {
return true, common.NotImplementedError return true, common.ErrNotImplementedError
} }
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
ret := make([]MemoryMapsStat, 0) var ret []MemoryMapsStat
return &ret, common.NotImplementedError return &ret, common.ErrNotImplementedError
} }
func NewProcess(pid int32) (*Process, error) { func NewProcess(pid int32) (*Process, error) {
@ -272,20 +272,20 @@ func NewProcess(pid int32) (*Process, error) {
} }
func (p *Process) SendSignal(sig syscall.Signal) error { func (p *Process) SendSignal(sig syscall.Signal) error {
return common.NotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Suspend() error { func (p *Process) Suspend() error {
return common.NotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Resume() error { func (p *Process) Resume() error {
return common.NotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Terminate() error { func (p *Process) Terminate() error {
return common.NotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Kill() error { func (p *Process) Kill() error {
return common.NotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) getFromSnapProcess(pid int32) (int32, int32, string, error) { func (p *Process) getFromSnapProcess(pid int32) (int32, int32, string, error) {
@ -328,7 +328,7 @@ func processes() ([]*Process, error) {
} }
results := make([]*Process, 0, len(dst)) results := make([]*Process, 0, len(dst))
for _, proc := range dst { for _, proc := range dst {
p, err := NewProcess(int32(proc.ProcessId)) p, err := NewProcess(int32(proc.ProcessID))
if err != nil { if err != nil {
continue continue
} }

@ -0,0 +1,134 @@
# This script is a helper of migration to gopsutil v2 using gorename
#
# go get golang.org/x/tools/cmd/gorename
IFS=$'\n'
## Part 1. rename Functions to pass golint. ex) cpu.CPUTimesStat -> cpu.TimesStat
#
# Note:
# process has IOCounters() for file IO, and also NetIOCounters() for Net IO.
# This scripts replace process.NetIOCounters() to IOCounters().
# So you need hand-fixing process.
TARGETS=`cat <<EOF
CPUTimesStat -> TimesStat
CPUInfoStat -> InfoStat
CPUTimes -> Times
CPUInfo -> Info
CPUCounts -> Counts
CPUPercent -> Percent
DiskUsageStat -> UsageStat
DiskPartitionStat -> PartitionStat
DiskIOCountersStat -> IOCountersStat
DiskPartitions -> Partitions
DiskIOCounters -> IOCounters
DiskUsage -> Usage
HostInfoStat -> InfoStat
HostInfo -> Info
GetVirtualization -> Virtualization
GetPlatformInformation -> PlatformInformation
LoadAvgStat -> AvgStat
LoadAvg -> Avg
NetIOCountersStat -> IOCountersStat
NetConnectionStat -> ConnectionStat
NetProtoCountersStat -> ProtoCountersStat
NetInterfaceAddr -> InterfaceAddr
NetInterfaceStat -> InterfaceStat
NetFilterStat -> FilterStat
NetInterfaces -> Interfaces
getNetIOCountersAll -> getIOCountersAll
NetIOCounters -> IOCounters
NetIOCountersByFile -> IOCountersByFile
NetProtoCounters -> ProtoCounters
NetFilterCounters -> FilterCounters
NetConnections -> Connections
NetConnectionsPid -> ConnectionsPid
Uid -> UID
Id -> ID
convertCpuTimes -> convertCPUTimes
EOF`
for T in $TARGETS
do
echo $T
gofmt -w -r "$T" ./*.go
done
###### Part 2 rename JSON key name
## Google JSOn style
## https://google.github.io/styleguide/jsoncstyleguide.xml
sed -i "" 's/guest_nice/guestNice/g' cpu/*.go
sed -i "" 's/vendor_id/vendorId/g' cpu/*.go
sed -i "" 's/physical_id/physicalId/g' cpu/*.go
sed -i "" 's/model_name/modelName/g' cpu/*.go
sed -i "" 's/cache_size/cacheSize/g' cpu/*.go
sed -i "" 's/core_id/coreId/g' cpu/*.go
sed -i "" 's/inodes_total/inodesTotal/g' disk/*.go
sed -i "" 's/inodes_used/inodesUsed/g' disk/*.go
sed -i "" 's/inodes_free/inodesFree/g' disk/*.go
sed -i "" 's/inodes_used_percent/inodesUsedPercent/g' disk/*.go
sed -i "" 's/read_count/readCount/g' disk/*.go
sed -i "" 's/write_count/writeCount/g' disk/*.go
sed -i "" 's/read_bytes/readBytes/g' disk/*.go
sed -i "" 's/write_bytes/writeBytes/g' disk/*.go
sed -i "" 's/read_time/readTime/g' disk/*.go
sed -i "" 's/write_time/writeTime/g' disk/*.go
sed -i "" 's/io_time/ioTime/g' disk/*.go
sed -i "" 's/serial_number/serialNumber/g' disk/*.go
sed -i "" 's/used_percent/usedPercent/g' disk/*.go
sed -i "" 's/inodesUsed_percent/inodesUsedPercent/g' disk/*.go
sed -i "" 's/total_cache/totalCache/g' docker/*.go
sed -i "" 's/total_rss_huge/totalRssHuge/g' docker/*.go
sed -i "" 's/total_rss/totalRss/g' docker/*.go
sed -i "" 's/total_mapped_file/totalMappedFile/g' docker/*.go
sed -i "" 's/total_pgpgin/totalPgpgin/g' docker/*.go
sed -i "" 's/total_pgpgout/totalPgpgout/g' docker/*.go
sed -i "" 's/total_pgfault/totalPgfault/g' docker/*.go
sed -i "" 's/total_pgmajfault/totalPgmajfault/g' docker/*.go
sed -i "" 's/total_inactive_anon/totalInactiveAnon/g' docker/*.go
sed -i "" 's/total_active_anon/totalActiveAnon/g' docker/*.go
sed -i "" 's/total_inactive_file/totalInactiveFile/g' docker/*.go
sed -i "" 's/total_active_file/totalActiveFile/g' docker/*.go
sed -i "" 's/total_unevictable/totalUnevictable/g' docker/*.go
sed -i "" 's/mem_usage_in_bytes/memUsageInBytes/g' docker/*.go
sed -i "" 's/mem_max_usage_in_bytes/memMaxUsageInBytes/g' docker/*.go
sed -i "" 's/memory.limit_in_bytes/memoryLimitInBbytes/g' docker/*.go
sed -i "" 's/memory.failcnt/memoryFailcnt/g' docker/*.go
sed -i "" 's/mapped_file/mappedFile/g' docker/*.go
sed -i "" 's/container_id/containerID/g' docker/*.go
sed -i "" 's/rss_huge/rssHuge/g' docker/*.go
sed -i "" 's/inactive_anon/inactiveAnon/g' docker/*.go
sed -i "" 's/active_anon/activeAnon/g' docker/*.go
sed -i "" 's/inactive_file/inactiveFile/g' docker/*.go
sed -i "" 's/active_file/activeFile/g' docker/*.go
sed -i "" 's/hierarchical_memory_limit/hierarchicalMemoryLimit/g' docker/*.go
sed -i "" 's/boot_time/bootTime/g' host/*.go
sed -i "" 's/platform_family/platformFamily/g' host/*.go
sed -i "" 's/platform_version/platformVersion/g' host/*.go
sed -i "" 's/virtualization_system/virtualizationSystem/g' host/*.go
sed -i "" 's/virtualization_role/virtualizationRole/g' host/*.go
sed -i "" 's/used_percent/usedPercent/g' mem/*.go
sed -i "" 's/bytes_sent/bytesSent/g' net/*.go
sed -i "" 's/bytes_recv/bytesRecv/g' net/*.go
sed -i "" 's/packets_sent/packetsSent/g' net/*.go
sed -i "" 's/packets_recv/packetsRecv/g' net/*.go
sed -i "" 's/conntrack_count/conntrackCount/g' net/*.go
sed -i "" 's/conntrack_max/conntrackMax/g' net/*.go
sed -i "" 's/read_count/readCount/g' process/*.go
sed -i "" 's/write_count/writeCount/g' process/*.go
sed -i "" 's/read_bytes/readBytes/g' process/*.go
sed -i "" 's/write_bytes/writeBytes/g' process/*.go
sed -i "" 's/shared_clean/sharedClean/g' process/*.go
sed -i "" 's/shared_dirty/sharedDirty/g' process/*.go
sed -i "" 's/private_clean/privateClean/g' process/*.go
sed -i "" 's/private_dirty/privateDirty/g' process/*.go
Loading…
Cancel
Save