Merge branch 'master' of github.com:shirou/gopsutil

pull/4/head
Shirou WAKAYAMA 11 years ago
commit f5a85e6b55

@ -102,7 +102,7 @@ Current Status
- disk_partitions (linux, freebsd, windows) - disk_partitions (linux, freebsd, windows)
- disk_io_counters (linux) - disk_io_counters (linux)
- disk_usage (linux, freebsd, windows) - disk_usage (linux, freebsd, windows)
- net_io_counters (linux, windows) - net_io_counters (linux, freebsd, windows)
- boot_time (linux, freebsd, windows(but little broken)) - boot_time (linux, freebsd, windows(but little broken))
- users (linux, freebsd) - users (linux, freebsd)
- pids (linux, freebsd) - pids (linux, freebsd)

@ -58,19 +58,19 @@ func byteToString(orig []byte) string {
} }
// Parse to int32 without error // Parse to int32 without error
func parseInt32(val string) int32 { func mustParseInt32(val string) int32 {
vv, _ := strconv.ParseInt(val, 10, 32) vv, _ := strconv.ParseInt(val, 10, 32)
return int32(vv) return int32(vv)
} }
// Parse to uint64 without error // Parse to uint64 without error
func parseUint64(val string) uint64 { func mustParseUint64(val string) uint64 {
vv, _ := strconv.ParseInt(val, 10, 64) vv, _ := strconv.ParseInt(val, 10, 64)
return uint64(vv) return uint64(vv)
} }
// Parse to Float64 without error // Parse to Float64 without error
func parseFloat64(val string) float64 { func mustParseFloat64(val string) float64 {
vv, _ := strconv.ParseFloat(val, 64) vv, _ := strconv.ParseFloat(val, 64)
return vv return vv
} }

@ -62,12 +62,12 @@ func CPUInfo() ([]CPUInfoStat, error) {
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]
c.Mhz = parseFloat64(matches[2]) c.Mhz = mustParseFloat64(matches[2])
} else if matches := regexp.MustCompile(`Origin = "(.+)" Id = (.+) Family = (.+) Model = (.+) Stepping = (.+)`).FindStringSubmatch(line); matches != nil { } else if matches := regexp.MustCompile(`Origin = "(.+)" Id = (.+) Family = (.+) Model = (.+) Stepping = (.+)`).FindStringSubmatch(line); matches != nil {
c.VendorID = matches[1] c.VendorID = matches[1]
c.Family = matches[3] c.Family = matches[3]
c.Model = matches[4] c.Model = matches[4]
c.Stepping = parseInt32(matches[5]) c.Stepping = mustParseInt32(matches[5])
} else if matches := regexp.MustCompile(`Features=.+<(.+)>`).FindStringSubmatch(line); matches != nil { } else if matches := regexp.MustCompile(`Features=.+<(.+)>`).FindStringSubmatch(line); matches != nil {
for _, v := range strings.Split(matches[1], ",") { for _, v := range strings.Split(matches[1], ",") {
c.Flags = append(c.Flags, strings.ToLower(v)) c.Flags = append(c.Flags, strings.ToLower(v))
@ -78,7 +78,7 @@ func CPUInfo() ([]CPUInfoStat, error) {
} }
} else if matches := regexp.MustCompile(`Logical CPUs per core: (\d+)`).FindStringSubmatch(line); matches != nil { } else if matches := regexp.MustCompile(`Logical CPUs per core: (\d+)`).FindStringSubmatch(line); matches != nil {
// FIXME: no this line? // FIXME: no this line?
c.Cores = parseInt32(matches[1]) c.Cores = mustParseInt32(matches[1])
} }
} }

@ -46,7 +46,7 @@ func CPUInfo() ([]CPUInfoStat, error) {
switch key { switch key {
case "processor": case "processor":
c = CPUInfoStat{} c = CPUInfoStat{}
c.CPU = parseInt32(value) c.CPU = mustParseInt32(value)
case "vendor_id": case "vendor_id":
c.VendorID = value c.VendorID = value
case "cpu family": case "cpu family":
@ -56,17 +56,17 @@ func CPUInfo() ([]CPUInfoStat, error) {
case "model name": case "model name":
c.ModelName = value c.ModelName = value
case "stepping": case "stepping":
c.Stepping = parseInt32(value) c.Stepping = mustParseInt32(value)
case "cpu MHz": case "cpu MHz":
c.Mhz = parseFloat64(value) c.Mhz = mustParseFloat64(value)
case "cache size": case "cache size":
c.CacheSize = parseInt32(strings.Replace(value, " KB", "", 1)) c.CacheSize = mustParseInt32(strings.Replace(value, " KB", "", 1))
case "physical id": case "physical id":
c.PhysicalID = value c.PhysicalID = value
case "core id": case "core id":
c.CoreID = value c.CoreID = value
case "cpu cores": case "cpu cores":
c.Cores = parseInt32(value) c.Cores = mustParseInt32(value)
case "flags": case "flags":
c.Flags = strings.Split(value, ",") c.Flags = strings.Split(value, ",")
} }

@ -69,12 +69,12 @@ func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
for _, line := range lines { for _, line := range lines {
fields := strings.Fields(line) fields := strings.Fields(line)
name := fields[2] name := fields[2]
reads := parseUint64(fields[3]) reads := mustParseUint64(fields[3])
rbytes := parseUint64(fields[5]) rbytes := mustParseUint64(fields[5])
rtime := parseUint64(fields[6]) rtime := mustParseUint64(fields[6])
writes := parseUint64(fields[7]) writes := mustParseUint64(fields[7])
wbytes := parseUint64(fields[9]) wbytes := mustParseUint64(fields[9])
wtime := parseUint64(fields[10]) wtime := mustParseUint64(fields[10])
if stringContains(partitions, name) { if stringContains(partitions, name) {
d := DiskIOCountersStat{ d := DiskIOCountersStat{
Name: name, Name: name,

@ -8,7 +8,7 @@ import (
// This is not in the psutil but it useful. // This is not in the psutil but it useful.
type HostInfoStat struct { type HostInfoStat struct {
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
Uptime int64 `json:"uptime"` Uptime uint64 `json:"uptime"`
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

@ -7,19 +7,41 @@ import (
"encoding/binary" "encoding/binary"
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec"
"runtime"
"strconv" "strconv"
"strings" "strings"
"unsafe" "unsafe"
) )
func HostInfo() (*HostInfoStat, error) { func HostInfo() (*HostInfoStat, error) {
ret := &HostInfoStat{} ret := &HostInfoStat{
OS: runtime.GOOS,
PlatformFamily: "freebsd",
}
hostname, err := os.Hostname() hostname, err := os.Hostname()
ret.Hostname = hostname
if err != nil { if err != nil {
return ret, err return ret, err
} }
ret.Hostname = hostname
out, err := exec.Command("uname", "-s").Output()
if err == nil {
ret.Platform = strings.ToLower(strings.TrimSpace(string(out)))
}
out, err = exec.Command("uname", "-r").Output()
if err == nil {
ret.PlatformVersion = strings.ToLower(strings.TrimSpace(string(out)))
}
values, err := doSysctrl("kern.boottime")
if err == nil {
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
v := strings.Replace(values[2], ",", "", 1)
ret.Uptime = mustParseUint64(v)
}
return ret, nil return ret, nil
} }

@ -38,16 +38,20 @@ func HostInfo() (*HostInfoStat, error) {
ret.PlatformFamily = family ret.PlatformFamily = family
ret.PlatformVersion = version ret.PlatformVersion = version
} }
uptime, err := BootTime()
if err == nil {
ret.Uptime = uptime
}
return ret, nil return ret, nil
} }
func BootTime() (int64, error) { func BootTime() (uint64, error) {
sysinfo := &syscall.Sysinfo_t{} sysinfo := &syscall.Sysinfo_t{}
if err := syscall.Sysinfo(sysinfo); err != nil { if err := syscall.Sysinfo(sysinfo); err != nil {
return 0, err return 0, err
} }
return int64(sysinfo.Uptime), nil return uint64(sysinfo.Uptime), nil
} }
func Users() ([]UserStat, error) { func Users() ([]UserStat, error) {

@ -26,7 +26,7 @@ func HostInfo() (*HostInfoStat, error) {
return ret, syscall.GetLastError() return ret, syscall.GetLastError()
} }
ret.Uptime = int64(uptimemsec) / 1000 ret.Uptime = uint64(uptimemsec) / 1000
procs, err := Pids() procs, err := Pids()
if err != nil { if err != nil {
@ -38,7 +38,7 @@ func HostInfo() (*HostInfoStat, error) {
return ret, nil return ret, nil
} }
func BootTime() (int64, error) { func BootTime() (uint64, error) {
var lpSystemTimeAsFileTime FILETIME var lpSystemTimeAsFileTime FILETIME
r, _, _ := procGetSystemTimeAsFileTime.Call(uintptr(unsafe.Pointer(&lpSystemTimeAsFileTime))) r, _, _ := procGetSystemTimeAsFileTime.Call(uintptr(unsafe.Pointer(&lpSystemTimeAsFileTime)))
@ -56,7 +56,7 @@ func BootTime() (int64, error) {
} }
uptime := uint64(u) / 1000 uptime := uint64(u) / 1000
return int64(pt - uptime), nil return uint64(pt - uptime), nil
} }
func Users() ([]UserStat, error) { func Users() ([]UserStat, error) {

@ -10,7 +10,7 @@ import (
func VirtualMemory() (*VirtualMemoryStat, error) { func VirtualMemory() (*VirtualMemoryStat, error) {
pageSize, _ := doSysctrl("vm.stats.vm.v_page_size") pageSize, _ := doSysctrl("vm.stats.vm.v_page_size")
p := parseUint64(pageSize[0]) p := mustParseUint64(pageSize[0])
pageCount, _ := doSysctrl("vm.stats.vm.v_page_count") pageCount, _ := doSysctrl("vm.stats.vm.v_page_count")
free, _ := doSysctrl("vm.stats.vm.v_free_count") free, _ := doSysctrl("vm.stats.vm.v_free_count")
@ -21,13 +21,13 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
wired, _ := doSysctrl("vm.stats.vm.v_wire_count") wired, _ := doSysctrl("vm.stats.vm.v_wire_count")
ret := &VirtualMemoryStat{ ret := &VirtualMemoryStat{
Total: parseUint64(pageCount[0]) * p, Total: mustParseUint64(pageCount[0]) * p,
Free: parseUint64(free[0]) * p, Free: mustParseUint64(free[0]) * p,
Active: parseUint64(active[0]) * p, Active: mustParseUint64(active[0]) * p,
Inactive: parseUint64(inactive[0]) * p, Inactive: mustParseUint64(inactive[0]) * p,
Cached: parseUint64(cache[0]) * p, Cached: mustParseUint64(cache[0]) * p,
Buffers: parseUint64(buffer[0]), Buffers: mustParseUint64(buffer[0]),
Wired: parseUint64(wired[0]) * p, Wired: mustParseUint64(wired[0]) * p,
} }
// TODO: platform independent (worked freebsd?) // TODO: platform independent (worked freebsd?)
@ -57,10 +57,10 @@ func SwapMemory() (*SwapMemoryStat, error) {
u := strings.Replace(values[4], "%", "", 1) u := strings.Replace(values[4], "%", "", 1)
ret = &SwapMemoryStat{ ret = &SwapMemoryStat{
Total: parseUint64(values[1]), Total: mustParseUint64(values[1]),
Used: parseUint64(values[2]), Used: mustParseUint64(values[2]),
Free: parseUint64(values[3]), Free: mustParseUint64(values[3]),
UsedPercent: parseFloat64(u), UsedPercent: mustParseFloat64(u),
} }
} }

@ -3,9 +3,43 @@
package gopsutil package gopsutil
import ( import (
"errors" "os/exec"
"strings"
) )
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
return nil, errors.New("not implemented yet") out, err := exec.Command("/usr/bin/netstat", "-ibdn").Output()
if err != nil {
return nil, err
}
lines := strings.Split(string(out), "\n")
ret := make([]NetIOCountersStat, 0, len(lines)-1)
for _, line := range lines {
values := strings.Fields(line)
if len(values) < 1 || values[0] == "Name" {
continue
}
base := 1
// sometimes Address is ommitted
if len(values) < 13 {
base = 0
}
n := NetIOCountersStat{
Name: values[0],
PacketsRecv: mustParseUint64(values[base+3]),
Errin: mustParseUint64(values[base+4]),
Dropin: mustParseUint64(values[base+5]),
BytesRecv: mustParseUint64(values[base+6]),
PacketsSent: mustParseUint64(values[base+7]),
Errout: mustParseUint64(values[base+8]),
BytesSent: mustParseUint64(values[base+9]),
Dropout: mustParseUint64(values[base+11]),
}
ret = append(ret, n)
}
return ret, nil
} }

@ -24,13 +24,13 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
} }
nic := NetIOCountersStat{ nic := NetIOCountersStat{
Name: strings.Trim(fields[0], ":"), Name: strings.Trim(fields[0], ":"),
BytesRecv: parseUint64(fields[1]), BytesRecv: mustParseUint64(fields[1]),
Errin: parseUint64(fields[2]), Errin: mustParseUint64(fields[2]),
Dropin: parseUint64(fields[3]), Dropin: mustParseUint64(fields[3]),
BytesSent: parseUint64(fields[9]), BytesSent: mustParseUint64(fields[9]),
PacketsSent: parseUint64(fields[10]), PacketsSent: mustParseUint64(fields[10]),
Errout: parseUint64(fields[11]), Errout: mustParseUint64(fields[11]),
Dropout: parseUint64(fields[12]), Dropout: mustParseUint64(fields[12]),
} }
ret = append(ret, nic) ret = append(ret, nic)
} }

@ -234,25 +234,25 @@ func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
v := strings.Trim(field[1], " kB") // remove last "kB" v := strings.Trim(field[1], " kB") // remove last "kB"
switch field[0] { switch field[0] {
case "Size": case "Size":
m.Size = parseUint64(v) m.Size = mustParseUint64(v)
case "Rss": case "Rss":
m.Rss = parseUint64(v) m.Rss = mustParseUint64(v)
case "Pss": case "Pss":
m.Pss = parseUint64(v) m.Pss = mustParseUint64(v)
case "Shared_Clean": case "Shared_Clean":
m.SharedClean = parseUint64(v) m.SharedClean = mustParseUint64(v)
case "Shared_Dirty": case "Shared_Dirty":
m.SharedDirty = parseUint64(v) m.SharedDirty = mustParseUint64(v)
case "Private_Clean": case "Private_Clean":
m.PrivateClean = parseUint64(v) m.PrivateClean = mustParseUint64(v)
case "Private_Dirty": case "Private_Dirty":
m.PrivateDirty = parseUint64(v) m.PrivateDirty = mustParseUint64(v)
case "Referenced": case "Referenced":
m.Referenced = parseUint64(v) m.Referenced = mustParseUint64(v)
case "Anonymous": case "Anonymous":
m.Anonymous = parseUint64(v) m.Anonymous = mustParseUint64(v)
case "Swap": case "Swap":
m.Swap = parseUint64(v) m.Swap = mustParseUint64(v)
} }
} }
return m return m
@ -301,7 +301,7 @@ func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) {
} }
o := &OpenFilesStat{ o := &OpenFilesStat{
Path: filepath, Path: filepath,
Fd: parseUint64(fd), Fd: mustParseUint64(fd),
} }
openfiles = append(openfiles, o) openfiles = append(openfiles, o)
} }
@ -368,13 +368,13 @@ func (p *Process) fillFromIO() (*IOCountersStat, error) {
} }
switch field[0] { switch field[0] {
case "rchar": case "rchar":
ret.ReadCount = parseInt32(strings.Trim(field[1], " \t")) ret.ReadCount = mustParseInt32(strings.Trim(field[1], " \t"))
case "wchar": case "wchar":
ret.WriteCount = parseInt32(strings.Trim(field[1], " \t")) ret.WriteCount = mustParseInt32(strings.Trim(field[1], " \t"))
case "read_bytes": case "read_bytes":
ret.ReadBytes = parseInt32(strings.Trim(field[1], " \t")) ret.ReadBytes = mustParseInt32(strings.Trim(field[1], " \t"))
case "write_bytes": case "write_bytes":
ret.WriteBytes = parseInt32(strings.Trim(field[1], " \t")) ret.WriteBytes = mustParseInt32(strings.Trim(field[1], " \t"))
} }
} }
@ -391,8 +391,8 @@ func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) {
} }
fields := strings.Split(string(contents), " ") fields := strings.Split(string(contents), " ")
rss := parseUint64(fields[0]) * PAGESIZE rss := mustParseUint64(fields[0]) * PAGESIZE
vms := parseUint64(fields[1]) * PAGESIZE vms := mustParseUint64(fields[1]) * PAGESIZE
memInfo := &MemoryInfoStat{ memInfo := &MemoryInfoStat{
RSS: rss, RSS: rss,
VMS: vms, VMS: vms,
@ -400,10 +400,10 @@ func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) {
memInfoEx := &MemoryInfoExStat{ memInfoEx := &MemoryInfoExStat{
RSS: rss, RSS: rss,
VMS: vms, VMS: vms,
Shared: parseUint64(fields[2]) * PAGESIZE, Shared: mustParseUint64(fields[2]) * PAGESIZE,
Text: parseUint64(fields[3]) * PAGESIZE, Text: mustParseUint64(fields[3]) * PAGESIZE,
Lib: parseUint64(fields[4]) * PAGESIZE, Lib: mustParseUint64(fields[4]) * PAGESIZE,
Dirty: parseUint64(fields[5]) * PAGESIZE, Dirty: mustParseUint64(fields[5]) * PAGESIZE,
} }
return memInfo, memInfoEx, nil return memInfo, memInfoEx, nil
@ -443,18 +443,18 @@ func (p *Process) fillFromStatus() (string, string, []int32, []int32, int32, *Nu
// case "PPid": // filled by fillFromStat // case "PPid": // filled by fillFromStat
case "Uid": case "Uid":
for _, i := range strings.Split(field[1], "\t") { for _, i := range strings.Split(field[1], "\t") {
uids = append(uids, parseInt32(i)) uids = append(uids, mustParseInt32(i))
} }
case "Gid": case "Gid":
for _, i := range strings.Split(field[1], "\t") { for _, i := range strings.Split(field[1], "\t") {
gids = append(gids, parseInt32(i)) gids = append(gids, mustParseInt32(i))
} }
case "Threads": case "Threads":
numThreads = parseInt32(field[1]) numThreads = mustParseInt32(field[1])
case "voluntary_ctxt_switches": case "voluntary_ctxt_switches":
vol = parseInt32(field[1]) vol = mustParseInt32(field[1])
case "nonvoluntary_ctxt_switches": case "nonvoluntary_ctxt_switches":
unvol = parseInt32(field[1]) unvol = mustParseInt32(field[1])
} }
} }
@ -477,10 +477,10 @@ func (p *Process) fillFromStat() (string, int32, *CPUTimesStat, int64, int32, er
termmap, err := getTerminalMap() termmap, err := getTerminalMap()
terminal := "" terminal := ""
if err == nil { if err == nil {
terminal = termmap[parseUint64(fields[6])] terminal = termmap[mustParseUint64(fields[6])]
} }
ppid := parseInt32(fields[3]) ppid := mustParseInt32(fields[3])
utime, _ := strconv.ParseFloat(fields[13], 64) utime, _ := strconv.ParseFloat(fields[13], 64)
stime, _ := strconv.ParseFloat(fields[14], 64) stime, _ := strconv.ParseFloat(fields[14], 64)
@ -491,10 +491,10 @@ func (p *Process) fillFromStat() (string, int32, *CPUTimesStat, int64, int32, er
} }
bootTime, _ := BootTime() bootTime, _ := BootTime()
ctime := ((parseUint64(fields[21]) / uint64(CLOCK_TICKS)) + uint64(bootTime)) * 1000 ctime := ((mustParseUint64(fields[21]) / uint64(CLOCK_TICKS)) + uint64(bootTime)) * 1000
createTime := int64(ctime) createTime := int64(ctime)
// p.Nice = parseInt32(fields[18]) // p.Nice = mustParseInt32(fields[18])
// use syscall instead of parse Stat file // use syscall instead of parse Stat file
snice, _ := syscall.Getpriority(PRIO_PROCESS, int(pid)) snice, _ := syscall.Getpriority(PRIO_PROCESS, int(pid))
nice := int32(snice) // FIXME: is this true? nice := int32(snice) // FIXME: is this true?

Loading…
Cancel
Save