From c312c3f35f15eeb0aaea9997d72fed387f39dbd2 Mon Sep 17 00:00:00 2001 From: WAKAYAMA shirou Date: Fri, 16 May 2014 15:33:23 +0900 Subject: [PATCH] virtual_memory and swap_memory on FreeBSD is implemented. --- README.rst | 6 +++--- common.go | 8 +++++++ mem_freebsd.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++-- mem_test.go | 1 - 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 9e102474..221a3ae4 100644 --- a/README.rst +++ b/README.rst @@ -67,12 +67,12 @@ Current Status - cpu_times (linux, freebsd) - cpu_count (linux, freebsd, windows) - - virtual_memory (linux, windows) - - swap_memory (linux) + - virtual_memory (linux, freebsd, windows) + - swap_memory (linux, freebsd) - disk_partitions (linux, freebsd, windows) - disk_io_counters (linux) - disk_usage (linux, freebsd, windows) - - net_io_counters (linux) + - net_io_counters (linux, windows) - boot_time (linux, freebsd, windows(but little broken)) - users (linux, freebsd) - pids (linux, freebsd) diff --git a/common.go b/common.go index 91303034..9a15d5ef 100644 --- a/common.go +++ b/common.go @@ -68,6 +68,14 @@ func parseUint64(val string) uint64 { return uint64(vv) } +// Parse to Float64 without error +func parseFloat64(val string) float64 { + vv, _ := strconv.ParseFloat(val, 64) + return vv +} + + + // Check the target string slice containes src or not func stringContains(target []string, src string) bool { for _, t := range target { diff --git a/mem_freebsd.go b/mem_freebsd.go index 8a4ca05d..16e0f02f 100644 --- a/mem_freebsd.go +++ b/mem_freebsd.go @@ -2,14 +2,67 @@ package gopsutil +import ( + "os/exec" + "strings" +) + func VirtualMemory() (*VirtualMemoryStat, error) { - ret := &VirtualMemoryStat{} + + pageSize, _ := doSysctrl("vm.stats.vm.v_page_size") + p := parseUint64(pageSize[0]) + + pageCount, _ := doSysctrl("vm.stats.vm.v_page_count") + free, _ := doSysctrl("vm.stats.vm.v_free_count") + active, _ := doSysctrl("vm.stats.vm.v_active_count") + inactive, _ := doSysctrl("vm.stats.vm.v_inactive_count") + cache, _ := doSysctrl("vm.stats.vm.v_cache_count") + buffer, _ := doSysctrl("vfs.bufspace") + wired, _ := doSysctrl("vm.stats.vm.v_wire_count") + + ret := &VirtualMemoryStat{ + Total: parseUint64(pageCount[0]) * p, + Free: parseUint64(free[0]) * p, + Active: parseUint64(active[0]) * p, + Inactive: parseUint64(inactive[0]) * p, + Cached: parseUint64(cache[0]) * p, + Buffers: parseUint64(buffer[0]), + Wired: parseUint64(wired[0]) * p, + } + + // TODO: platform independent (worked freebsd?) + ret.Available = ret.Free + ret.Buffers + ret.Cached + + ret.Used = ret.Total - ret.Free + ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0 return ret, nil } +// Return swapinfo +// FreeBSD can have multiple swap devices. but use only first device func SwapMemory() (*SwapMemoryStat, error) { - ret := &SwapMemoryStat{} + out, err := exec.Command("swapinfo").Output() + if err != nil { + return nil, err + } + var ret *SwapMemoryStat + for _, line := range strings.Split(string(out), "\n") { + values := strings.Fields(line) + // skip title line + if len(values) == 0 || values[0] == "Device" { + continue + } + + u := strings.Replace(values[4], "%", "", 1) + + ret = &SwapMemoryStat{ + Total: parseUint64(values[1]), + Used: parseUint64(values[2]), + Free: parseUint64(values[3]), + UsedPercent: parseFloat64(u), + } + } return ret, nil } diff --git a/mem_test.go b/mem_test.go index 9426175d..7d665501 100644 --- a/mem_test.go +++ b/mem_test.go @@ -15,7 +15,6 @@ func TestVirtual_memory(t *testing.T) { if v == empty { t.Errorf("error %v", v) } - } func TestSwap_memory(t *testing.T) {