Godep update gopsutil to get darwin mem fix

This commit is contained in:
Cameron Sparr 2015-09-18 11:03:04 -07:00
parent 74da03d9fa
commit 167b8b8eb8
8 changed files with 173 additions and 43 deletions

28
Godeps/Godeps.json generated
View File

@ -143,38 +143,38 @@
}, },
{ {
"ImportPath": "github.com/shirou/gopsutil/common", "ImportPath": "github.com/shirou/gopsutil/common",
"Comment": "1.0.0-148-ga369a88", "Comment": "1.0.0-153-gc1313e7",
"Rev": "a369a8857c47ba9bcf8bbcf316897fa123d73639" "Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
}, },
{ {
"ImportPath": "github.com/shirou/gopsutil/cpu", "ImportPath": "github.com/shirou/gopsutil/cpu",
"Comment": "1.0.0-148-ga369a88", "Comment": "1.0.0-153-gc1313e7",
"Rev": "a369a8857c47ba9bcf8bbcf316897fa123d73639" "Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
}, },
{ {
"ImportPath": "github.com/shirou/gopsutil/disk", "ImportPath": "github.com/shirou/gopsutil/disk",
"Comment": "1.0.0-148-ga369a88", "Comment": "1.0.0-153-gc1313e7",
"Rev": "a369a8857c47ba9bcf8bbcf316897fa123d73639" "Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
}, },
{ {
"ImportPath": "github.com/shirou/gopsutil/docker", "ImportPath": "github.com/shirou/gopsutil/docker",
"Comment": "1.0.0-148-ga369a88", "Comment": "1.0.0-153-gc1313e7",
"Rev": "a369a8857c47ba9bcf8bbcf316897fa123d73639" "Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
}, },
{ {
"ImportPath": "github.com/shirou/gopsutil/load", "ImportPath": "github.com/shirou/gopsutil/load",
"Comment": "1.0.0-148-ga369a88", "Comment": "1.0.0-153-gc1313e7",
"Rev": "a369a8857c47ba9bcf8bbcf316897fa123d73639" "Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
}, },
{ {
"ImportPath": "github.com/shirou/gopsutil/mem", "ImportPath": "github.com/shirou/gopsutil/mem",
"Comment": "1.0.0-148-ga369a88", "Comment": "1.0.0-153-gc1313e7",
"Rev": "a369a8857c47ba9bcf8bbcf316897fa123d73639" "Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
}, },
{ {
"ImportPath": "github.com/shirou/gopsutil/net", "ImportPath": "github.com/shirou/gopsutil/net",
"Comment": "1.0.0-148-ga369a88", "Comment": "1.0.0-153-gc1313e7",
"Rev": "a369a8857c47ba9bcf8bbcf316897fa123d73639" "Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
}, },
{ {
"ImportPath": "github.com/streadway/amqp", "ImportPath": "github.com/streadway/amqp",

View File

@ -74,6 +74,10 @@ func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
} }
out, err := invoke.Command(lsof, cmd...) out, err := invoke.Command(lsof, cmd...)
if err != nil { if err != nil {
// if not pid found, lsof returnes code 1
if err.Error() == "exit status 1" && len(out) == 0 {
return []string{}, nil
}
return []string{}, err return []string{}, err
} }
lines := strings.Split(string(out), "\n") lines := strings.Split(string(out), "\n")

View File

@ -8,6 +8,8 @@ import (
"strings" "strings"
) )
// CallLsof invokes lsof to get connection informations.
// This is same as darwin currently.
func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) { func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
var cmd []string var cmd []string
if pid == 0 { // will get from all processes. if pid == 0 { // will get from all processes.
@ -22,6 +24,10 @@ func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
} }
out, err := invoke.Command(lsof, cmd...) out, err := invoke.Command(lsof, cmd...)
if err != nil { if err != nil {
// if not pid found, lsof returnes code 1
if err.Error() == "exit status 1" && len(out) == 0 {
return []string{}, nil
}
return []string{}, err return []string{}, err
} }
lines := strings.Split(string(out), "\n") lines := strings.Split(string(out), "\n")

View File

@ -20,45 +20,89 @@ func getPageSize() (uint64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
return p, nil return p, nil
} }
// Runs vm_stat and returns Free and inactive pages
func getVmStat(pagesize uint64, vms *VirtualMemoryStat) error {
out, err := exec.Command("vm_stat").Output()
if err != nil {
return err
}
return parseVmStat(string(out), pagesize, vms)
}
func parseVmStat(out string, pagesize uint64, vms *VirtualMemoryStat) error {
var err error
lines := strings.Split(out, "\n")
for _, line := range lines {
fields := strings.Split(line, ":")
if len(fields) < 2 {
continue
}
key := strings.TrimSpace(fields[0])
value := strings.Trim(fields[1], " .")
switch key {
case "Pages free":
free, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Free = free * pagesize
case "Pages inactive":
inactive, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Cached += inactive * pagesize
vms.Inactive = inactive * pagesize
case "Pages active":
active, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Active = active * pagesize
case "Pages wired down":
wired, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Wired = wired * pagesize
case "Pages purgeable":
purgeable, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Cached += purgeable * pagesize
}
}
return err
}
// VirtualMemory returns VirtualmemoryStat. // VirtualMemory returns VirtualmemoryStat.
func VirtualMemory() (*VirtualMemoryStat, error) { func VirtualMemory() (*VirtualMemoryStat, error) {
ret := &VirtualMemoryStat{}
p, err := getPageSize() p, err := getPageSize()
if err != nil { if err != nil {
return nil, err return nil, err
} }
t, err := common.DoSysctrl("hw.memsize")
total, err := common.DoSysctrl("hw.memsize")
if err != nil { if err != nil {
return nil, err return nil, err
} }
free, err := common.DoSysctrl("vm.page_free_count") total, err := strconv.ParseUint(t[0], 10, 64)
if err != nil { if err != nil {
return nil, err return nil, err
} }
parsed := make([]uint64, 0, 7) err = getVmStat(p, ret)
vv := []string{ if err != nil {
total[0], return nil, err
free[0],
}
for _, target := range vv {
t, err := strconv.ParseUint(target, 10, 64)
if err != nil {
return nil, err
}
parsed = append(parsed, t)
} }
ret := &VirtualMemoryStat{ ret.Available = ret.Free + ret.Cached
Total: parsed[0], ret.Total = total
Free: parsed[1] * p,
}
// TODO: platform independent (worked freebsd?)
ret.Available = ret.Free + ret.Buffers + ret.Cached
ret.Used = ret.Total - ret.Free ret.Used = ret.Total - ret.Free
ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0 ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0

View File

@ -0,0 +1,67 @@
// +build darwin
package mem
import (
"testing"
)
var vm_stat_out = `
Mach Virtual Memory Statistics: (page size of 4096 bytes)
Pages free: 105885.
Pages active: 725641.
Pages inactive: 449242.
Pages speculative: 6155.
Pages throttled: 0.
Pages wired down: 560835.
Pages purgeable: 128967.
"Translation faults": 622528839.
Pages copy-on-write: 17697839.
Pages zero filled: 311034413.
Pages reactivated: 4705104.
Pages purged: 5605610.
File-backed pages: 349192.
Anonymous pages: 831846.
Pages stored in compressor: 876507.
Pages occupied by compressor: 249167.
Decompressions: 4555025.
Compressions: 7524729.
Pageins: 40532443.
Pageouts: 126496.
Swapins: 2988073.
Swapouts: 3283599.
`
func TestParseVmStat(t *testing.T) {
ret := &VirtualMemoryStat{}
err := parseVmStat(vm_stat_out, 4096, ret)
if err != nil {
t.Errorf("Expected no error, got %s\n", err.Error())
}
if ret.Free != uint64(105885*4096) {
t.Errorf("Free pages, actual: %d, expected: %d", ret.Free,
105885*4096)
}
if ret.Inactive != uint64(449242*4096) {
t.Errorf("Inactive pages, actual: %d, expected: %d", ret.Inactive,
449242*4096)
}
if ret.Active != uint64(725641*4096) {
t.Errorf("Active pages, actual: %d, expected: %d", ret.Active,
725641*4096)
}
if ret.Wired != uint64(560835*4096) {
t.Errorf("Wired pages, actual: %d, expected: %d", ret.Wired,
560835*4096)
}
if ret.Cached != uint64(128967*4096+449242.*4096) {
t.Errorf("Cached pages, actual: %d, expected: %d", ret.Cached,
128967*4096+449242.*4096)
}
}

View File

@ -77,10 +77,8 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
Wired: parsed[6] * p, Wired: parsed[6] * p,
} }
// TODO: platform independent (worked freebsd?) ret.Available = ret.Inactive + ret.Cached + ret.Free
ret.Available = ret.Free + ret.Buffers + ret.Cached ret.Used = ret.Active + ret.Wired + ret.Cached
ret.Used = ret.Total - ret.Free
ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0 ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0
return ret, nil return ret, nil

View File

@ -91,8 +91,13 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
return ret, nil return ret, nil
} }
// Return a list of network connections opened by a process // Return a list of network connections opened.
func NetConnections(kind string) ([]NetConnectionStat, error) { func NetConnections(kind string) ([]NetConnectionStat, error) {
return NetConnectionsPid(kind, 0)
}
// Return a list of network connections opened by a process.
func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) {
var ret []NetConnectionStat var ret []NetConnectionStat
args := []string{"-i"} args := []string{"-i"}
@ -126,7 +131,7 @@ func NetConnections(kind string) ([]NetConnectionStat, error) {
} }
// we can not use -F filter to get all of required information at once. // we can not use -F filter to get all of required information at once.
r, err := common.CallLsof(invoke, 0, args...) r, err := common.CallLsof(invoke, pid, args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -90,7 +90,13 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
return ret, nil return ret, nil
} }
// Return a list of network connections opened.
func NetConnections(kind string) ([]NetConnectionStat, error) { func NetConnections(kind string) ([]NetConnectionStat, error) {
return NetConnectionsPid(kind, 0)
}
// Return a list of network connections opened by a process.
func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) {
var ret []NetConnectionStat var ret []NetConnectionStat
args := []string{"-i"} args := []string{"-i"}
@ -124,7 +130,7 @@ func NetConnections(kind string) ([]NetConnectionStat, error) {
} }
// we can not use -F filter to get all of required information at once. // we can not use -F filter to get all of required information at once.
r, err := common.CallLsof(invoke, 0, args...) r, err := common.CallLsof(invoke, pid, args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }