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

pull/4/head
Shirou WAKAYAMA 11 years ago
commit 1b320efd01

@ -65,8 +65,10 @@ Current Status
- cpu_count (linux, freebsd, windows) - cpu_count (linux, freebsd, windows)
- virtual_memory (linux, windows) - virtual_memory (linux, windows)
- swap_memory (linux) - swap_memory (linux)
- disk_partitions (freebsd, windows) - disk_partitions (linux, freebsd, windows)
- disk_io_counters (linux)
- disk_usage (linux, freebsd, windows) - disk_usage (linux, freebsd, windows)
- net_io_counters (linux)
- 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)
@ -74,19 +76,19 @@ Current Status
- Process class - Process class
- Pid (linux, freebsd, windows) - Pid (linux, freebsd, windows)
- Ppid (linux) - Ppid (linux, windows)
- Name (linux) - Name (linux)
- Cmdline (linux) - Cmdline (linux)
- Create_time (linux) - Create_time (linux)
- Status (linux) - Status (linux)
- Cwd (linux) - Cwd (linux)
- Exe (linux, freebsd) - Exe (linux, freebsd, windows)
- Uids (linux) - Uids (linux)
- Gids (linux) - Gids (linux)
- Terminal (linux) - Terminal (linux)
- Nice (linux) - Nice (linux)
- Num_fds (linux) - Num_fds (linux)
- Num_threads (linux) - Num_threads (linux, windows)
- Cpu_times (linux) - Cpu_times (linux)
- Memory_info (linux) - Memory_info (linux)
- Memory_info_ex (linux) - Memory_info_ex (linux)
@ -102,8 +104,6 @@ Current Status
- cpu_percent - cpu_percent
- cpu_times_percent - cpu_times_percent
- disk_io_counters
- net_io_counters
- net_connections - net_connections
- Process class - Process class
@ -142,11 +142,22 @@ New BSD License (same as psutil)
Related works Related works
----------------------- -----------------------
So many thanks!
- psutil: http://pythonhosted.org/psutil/ - psutil: http://pythonhosted.org/psutil/
- dstat: https://github.com/dagwieers/dstat - dstat: https://github.com/dagwieers/dstat
- gosiger: https://github.com/cloudfoundry/gosigar/ - gosiger: https://github.com/cloudfoundry/gosigar/
- goprocinfo: https://github.com/c9s/goprocinfo - goprocinfo: https://github.com/c9s/goprocinfo
- go-ps: https://github.com/mitchellh/go-ps - go-ps: https://github.com/mitchellh/go-ps
I have referenced these great works.
How to Contributing
---------------------------
1. Fork it
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
5. Create new Pull Request
My engilsh is terrible, documentation or correcting comments are also
welcome.

@ -68,3 +68,13 @@ func parseUint64(val string) uint64 {
vv, _ := strconv.ParseInt(val, 10, 64) vv, _ := strconv.ParseInt(val, 10, 64)
return uint64(vv) return uint64(vv)
} }
// Check the target string slice containes src or not
func stringContains(target []string, src string) bool {
for _, t := range target {
if t == src {
return true
}
}
return false
}

@ -19,6 +19,6 @@ type CPU_TimesStat struct {
Stolen float32 `json:"stolen"` Stolen float32 `json:"stolen"`
} }
func Cpu_counts() (int, error) { func Cpu_counts(logical bool) (int, error) {
return runtime.NumCPU(), nil return runtime.NumCPU(), nil
} }

@ -22,7 +22,7 @@ const (
) )
// TODO: get per cpus // TODO: get per cpus
func Cpu_times() ([]CPU_TimesStat, error) { func Cpu_times(percpu bool) ([]CPU_TimesStat, error) {
ret := make([]CPU_TimesStat, 0) ret := make([]CPU_TimesStat, 0)
cpu_time, err := do_sysctrl("kern.cp_time") cpu_time, err := do_sysctrl("kern.cp_time")

@ -8,7 +8,7 @@ import (
"strings" "strings"
) )
func Cpu_times() ([]CPU_TimesStat, error) { func Cpu_times(percpu bool) ([]CPU_TimesStat, error) {
ret := make([]CPU_TimesStat, 0) ret := make([]CPU_TimesStat, 0)
filename := "/proc/stat" filename := "/proc/stat"

@ -5,7 +5,7 @@ import (
) )
func TestCpu_times(t *testing.T) { func TestCpu_times(t *testing.T) {
v, err := Cpu_times() v, err := Cpu_times(false)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
@ -21,7 +21,7 @@ func TestCpu_times(t *testing.T) {
} }
func TestCpu_counts(t *testing.T) { func TestCpu_counts(t *testing.T) {
v, err := Cpu_counts() v, err := Cpu_counts(true)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }

@ -7,7 +7,7 @@ import (
"unsafe" "unsafe"
) )
func Cpu_times() ([]CPU_TimesStat, error) { func Cpu_times(percpu bool) ([]CPU_TimesStat, error) {
ret := make([]CPU_TimesStat, 0) ret := make([]CPU_TimesStat, 0)
var lpIdleTime FILETIME var lpIdleTime FILETIME

@ -22,4 +22,5 @@ type Disk_IO_CountersStat struct {
WriteBytes uint64 `json:"writeBytes"` WriteBytes uint64 `json:"writeBytes"`
ReadTime uint64 `json:"readTime"` ReadTime uint64 `json:"readTime"`
WriteTime uint64 `json:"writeTime"` WriteTime uint64 `json:"writeTime"`
Name string `json:"name"`
} }

@ -3,11 +3,12 @@
package gopsutil package gopsutil
import ( import (
"errors"
"syscall" "syscall"
"unsafe" "unsafe"
) )
func Disk_partitions() ([]Disk_partitionStat, error) { func Disk_partitions(all bool) ([]Disk_partitionStat, error) {
ret := make([]Disk_partitionStat, 0) ret := make([]Disk_partitionStat, 0)
// get length // get length
@ -81,6 +82,11 @@ func Disk_partitions() ([]Disk_partitionStat, error) {
return ret, nil return ret, nil
} }
func Disk_io_counters() (map[string]Disk_IO_CountersStat, error) {
ret := make(map[string]Disk_IO_CountersStat, 0)
return ret, errors.New("Not implemented yet")
}
// This is borrowed from pkg/syscall/syscall_freebsd.go // This is borrowed from pkg/syscall/syscall_freebsd.go
// change Statfs_t to Statfs in order to get more information // change Statfs_t to Statfs in order to get more information
func Getfsstat(buf []Statfs, flags int) (n int, err error) { func Getfsstat(buf []Statfs, flags int) (n int, err error) {

@ -2,8 +2,92 @@
package gopsutil package gopsutil
func Disk_partitions() ([]Disk_partitionStat, error) { import (
"strings"
"unicode"
)
const (
SECTOR_SIZE = 512
)
// Get disk partitions.
// should use setmntent(3) but this implement use /etc/mtab file
func Disk_partitions(all bool) ([]Disk_partitionStat, error) {
ret := make([]Disk_partitionStat, 0) ret := make([]Disk_partitionStat, 0)
filename := "/etc/mtab"
lines, err := ReadLines(filename)
if err != nil {
return ret, err
}
for _, line := range lines {
fields := strings.Fields(line)
d := Disk_partitionStat{
Mountpoint: fields[1],
Fstype: fields[2],
Opts: fields[3],
}
ret = append(ret, d)
}
return ret, nil
}
func Disk_io_counters() (map[string]Disk_IO_CountersStat, error) {
ret := make(map[string]Disk_IO_CountersStat, 0)
// determine partitions we want to look for
filename := "/proc/partitions"
lines, err := ReadLines(filename)
if err != nil {
return ret, err
}
partitions := make([]string, 0)
for _, line := range lines[2:] {
fields := strings.Fields(line)
name := []rune(fields[3])
if unicode.IsDigit(name[len(name)-1]) {
partitions = append(partitions, fields[3])
} else {
// http://code.google.com/p/psutil/issues/detail?id=338
lenpart := len(partitions)
if lenpart == 0 || strings.HasPrefix(partitions[lenpart-1], fields[3]) {
partitions = append(partitions, fields[3])
}
}
}
filename = "/proc/diskstats"
lines, err = ReadLines(filename)
if err != nil {
return ret, err
}
for _, line := range lines {
fields := strings.Fields(line)
name := fields[2]
reads := parseUint64(fields[3])
rbytes := parseUint64(fields[5])
rtime := parseUint64(fields[6])
writes := parseUint64(fields[7])
wbytes := parseUint64(fields[9])
wtime := parseUint64(fields[10])
if stringContains(partitions, name) {
d := Disk_IO_CountersStat{
Name: name,
ReadBytes: rbytes * SECTOR_SIZE,
WriteBytes: wbytes * SECTOR_SIZE,
ReadCount: reads,
WriteCount: writes,
ReadTime: rtime,
WriteTime: wtime,
}
ret[name] = d
}
}
return ret, nil return ret, nil
} }

@ -1,8 +1,7 @@
package gopsutil package gopsutil
import ( import (
"encoding/json" // "fmt"
"fmt"
"runtime" "runtime"
"testing" "testing"
) )
@ -12,19 +11,29 @@ func TestDisk_usage(t *testing.T) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
path = "C:" path = "C:"
} }
v, err := Disk_usage(path) _, err := Disk_usage(path)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
d, _ := json.Marshal(v) // d, _ := json.Marshal(v)
fmt.Printf("%s\n", d) // fmt.Printf("%s\n", d)
} }
func TestDisk_partitions(t *testing.T) { func TestDisk_partitions(t *testing.T) {
v, err := Disk_partitions() _, err := Disk_partitions(false)
if err != nil { if err != nil {
t.Errorf("error %v", err) t.Errorf("error %v", err)
} }
d, _ := json.Marshal(v) }
fmt.Printf("%s\n", d)
func TestDisk_io_counters(t *testing.T) {
ret, err := Disk_io_counters()
if err != nil {
t.Errorf("error %v", err)
}
for _, io := range ret {
if io.Name == "" {
t.Errorf("io_counter error %v", io)
}
}
} }

@ -4,6 +4,7 @@ package gopsutil
import ( import (
"bytes" "bytes"
"errors"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -44,7 +45,7 @@ func Disk_usage(path string) (Disk_usageStat, error) {
return ret, nil return ret, nil
} }
func Disk_partitions() ([]Disk_partitionStat, error) { func Disk_partitions(all bool) ([]Disk_partitionStat, error) {
ret := make([]Disk_partitionStat, 0) ret := make([]Disk_partitionStat, 0)
lpBuffer := make([]byte, 254) lpBuffer := make([]byte, 254)
diskret, _, err := procGetLogicalDriveStringsW.Call( diskret, _, err := procGetLogicalDriveStringsW.Call(
@ -105,3 +106,8 @@ func Disk_partitions() ([]Disk_partitionStat, error) {
} }
return ret, nil return ret, nil
} }
func Disk_io_counters() (map[string]Disk_IO_CountersStat, error) {
ret := make(map[string]Disk_IO_CountersStat, 0)
return ret, errors.New("Not implemented yet")
}

@ -9,7 +9,7 @@ import (
func Net_io_counters() ([]Net_io_countersStat, error) { func Net_io_counters() ([]Net_io_countersStat, error) {
filename := "/proc/net/dev" filename := "/proc/net/dev"
lines, err := ReadLines(filename) lines, err := ReadLines(filename)
if err != nil{ if err != nil {
return make([]Net_io_countersStat, 0), err return make([]Net_io_countersStat, 0), err
} }
@ -19,7 +19,7 @@ func Net_io_counters() ([]Net_io_countersStat, error) {
for _, line := range lines[2:] { for _, line := range lines[2:] {
fields := strings.Fields(line) fields := strings.Fields(line)
if fields[0] == ""{ if fields[0] == "" {
continue continue
} }
nic := Net_io_countersStat{ nic := Net_io_countersStat{

@ -1,7 +1,7 @@
package gopsutil package gopsutil
type Process struct { type Process struct {
Pid int32 `json:"pid"` Pid int32 `json:"pid"`
} }
type Open_filesStat struct { type Open_filesStat struct {

@ -5,6 +5,7 @@ package gopsutil
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -30,106 +31,105 @@ func Pids() ([]int32, error) {
return ret, nil return ret, nil
} }
func (p *Process) Ppid() (int32, error) { func (p *Process) Ppid() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Name() (string, error) { func (p *Process) Name() (string, error) {
name := "" name := ""
return name, nil return name, errors.New("Not implemented yet")
} }
func (p *Process) Exe() (string, error) { func (p *Process) Exe() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Cmdline() (string, error) { func (p *Process) Cmdline() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
return p, nil return p, errors.New("Not implemented yet")
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Username() (string, error) { func (p *Process) Username() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Uids() ([]int32, error) { func (p *Process) Uids() ([]int32, error) {
uids := make([]int32, 0) uids := make([]int32, 0)
return uids, nil return uids, errors.New("Not implemented yet")
} }
func (p *Process) Gids() ([]int32, error) { func (p *Process) Gids() ([]int32, error) {
gids := make([]int32, 0) gids := make([]int32, 0)
return gids, nil return gids, errors.New("Not implemented yet")
} }
func (p *Process) Terminal() (string, error) { func (p *Process) Terminal() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Nice() (int32, error) { func (p *Process) Nice() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Ionice() (int32, error) { func (p *Process) Ionice() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Rlimit() ([]RlimitStat, error) { func (p *Process) Rlimit() ([]RlimitStat, error) {
rlimit := make([]RlimitStat, 0) rlimit := make([]RlimitStat, 0)
return rlimit, nil return rlimit, errors.New("Not implemented yet")
} }
func (p *Process) Io_counters() (*Io_countersStat, error) { func (p *Process) Io_counters() (*Io_countersStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Num_ctx_switches() (int32, error) { func (p *Process) Num_ctx_switches() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Num_fds() (int32, error) { func (p *Process) Num_fds() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Num_Threads() (int32, error) { func (p *Process) Num_Threads() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
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, nil return ret, errors.New("Not implemented yet")
} }
func (p *Process) Cpu_times() (*CPU_TimesStat, error) { func (p *Process) Cpu_times() (*CPU_TimesStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Cpu_percent() (int32, error) { func (p *Process) Cpu_percent() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Cpu_affinity() ([]int32, error) { func (p *Process) Cpu_affinity() ([]int32, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Memory_info() (*Memory_infoStat, error) { func (p *Process) Memory_info() (*Memory_infoStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Memory_info_ex() (*Memory_info_exStat, error) { func (p *Process) Memory_info_ex() (*Memory_info_exStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Memory_percent() (float32, error) { func (p *Process) Memory_percent() (float32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Children() ([]*Process, error) { func (p *Process) Children() ([]*Process, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Open_files() ([]Open_filesStat, error) { func (p *Process) Open_files() ([]Open_filesStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Connections() ([]Net_connectionStat, error) { func (p *Process) Connections() ([]Net_connectionStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Is_running() (bool, error) { func (p *Process) Is_running() (bool, error) {
return true, nil return true, errors.New("Not implemented yet")
} }
func (p *Process) Memory_Maps() (*[]Memory_mapsStat, error) { func (p *Process) Memory_Maps(grouped bool) (*[]Memory_mapsStat, error) {
ret := make([]Memory_mapsStat, 0) ret := make([]Memory_mapsStat, 0)
return &ret, nil return &ret, errors.New("Not implemented yet")
} }
func copy_params(k *Kinfo_proc, p *Process) error { func copy_params(k *Kinfo_proc, p *Process) error {

@ -3,6 +3,7 @@
package gopsutil package gopsutil
import ( import (
"errors"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -51,7 +52,7 @@ func NewProcess(pid int32) (*Process, error) {
func (p *Process) Ppid() (int32, error) { func (p *Process) Ppid() (int32, error) {
_, ppid, _, _, _, err := p.fillFromStat() _, ppid, _, _, _, err := p.fillFromStat()
if err != nil{ if err != nil {
return -1, err return -1, err
} }
return ppid, nil return ppid, nil
@ -73,7 +74,7 @@ func (p *Process) Cwd() (string, error) {
return p.fillFromCwd() return p.fillFromCwd()
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
_, status, _, _, _, err := p.fillFromStatus() _, status, _, _, _, err := p.fillFromStatus()
@ -101,32 +102,32 @@ func (p *Process) Gids() ([]int32, error) {
} }
func (p *Process) Terminal() (string, error) { func (p *Process) Terminal() (string, error) {
terminal, _, _, _, _, err := p.fillFromStat() terminal, _, _, _, _, err := p.fillFromStat()
if err != nil{ if err != nil {
return "", err return "", err
} }
return terminal, nil return terminal, nil
} }
func (p *Process) Nice() (int32, error) { func (p *Process) Nice() (int32, error) {
_, _, _, _, nice, err := p.fillFromStat() _, _, _, _, nice, err := p.fillFromStat()
if err != nil{ if err != nil {
return 0, err return 0, err
} }
return nice, nil return nice, nil
} }
func (p *Process) Ionice() (int32, error) { func (p *Process) Ionice() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Rlimit() ([]RlimitStat, error) { func (p *Process) Rlimit() ([]RlimitStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Io_counters() (*Io_countersStat, error) { func (p *Process) Io_counters() (*Io_countersStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Num_ctx_switches() (int32, error) { func (p *Process) Num_ctx_switches() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Num_fds() (int32, error) { func (p *Process) Num_fds() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Num_Threads() (int32, error) { func (p *Process) Num_Threads() (int32, error) {
_, _, _, _, num_threads, err := p.fillFromStatus() _, _, _, _, num_threads, err := p.fillFromStatus()
@ -141,16 +142,16 @@ func (p *Process) Threads() (map[string]string, error) {
} }
func (p *Process) Cpu_times() (*CPU_TimesStat, error) { func (p *Process) Cpu_times() (*CPU_TimesStat, error) {
_, _, cpu_times, _, _, err := p.fillFromStat() _, _, cpu_times, _, _, err := p.fillFromStat()
if err != nil{ if err != nil {
return nil, err return nil, err
} }
return cpu_times, nil return cpu_times, nil
} }
func (p *Process) Cpu_percent() (int32, error) { func (p *Process) Cpu_percent() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Cpu_affinity() ([]int32, error) { func (p *Process) Cpu_affinity() ([]int32, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Memory_info() (*Memory_infoStat, error) { func (p *Process) Memory_info() (*Memory_infoStat, error) {
mem_info, _, err := p.fillFromStatm() mem_info, _, err := p.fillFromStatm()
@ -167,27 +168,27 @@ func (p *Process) Memory_info_ex() (*Memory_info_exStat, error) {
return mem_info_ex, nil return mem_info_ex, nil
} }
func (p *Process) Memory_percent() (float32, error) { func (p *Process) Memory_percent() (float32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Children() ([]*Process, error) { func (p *Process) Children() ([]*Process, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Open_files() ([]Open_filesStat, error) { func (p *Process) Open_files() ([]Open_filesStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Connections() ([]Net_connectionStat, error) { func (p *Process) Connections() ([]Net_connectionStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Is_running() (bool, error) { func (p *Process) Is_running() (bool, error) {
return true, nil return true, errors.New("Not implemented yet")
} }
// Get memory maps from /proc/(pid)/smaps // Get memory maps from /proc/(pid)/smaps
func (p *Process) Memory_Maps() (*[]Memory_mapsStat, error) { func (p *Process) Memory_Maps(grouped bool) (*[]Memory_mapsStat, error) {
pid := p.Pid pid := p.Pid
ret := make([]Memory_mapsStat, 0) ret := make([]Memory_mapsStat, 0)
smapsPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "smaps") smapsPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "smaps")

@ -54,9 +54,10 @@ func Test_Process_memory_maps(t *testing.T) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
check_pid = 0 check_pid = 0
} }
return
ret, err := NewProcess(int32(check_pid)) ret, err := NewProcess(int32(check_pid))
mmaps, err := ret.Memory_Maps() mmaps, err := ret.Memory_Maps(false)
if err != nil { if err != nil {
t.Errorf("memory map get error %v", err) t.Errorf("memory map get error %v", err)
} }
@ -66,20 +67,19 @@ func Test_Process_memory_maps(t *testing.T) {
} }
func Test_Process_Ppid(t *testing.T) { func Test_Process_Ppid(t *testing.T) {
check_pid := os.Getpid() check_pid := os.Getpid()
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
check_pid = 0 check_pid = 7960
} }
ret, err := NewProcess(int32(check_pid)) ret, err := NewProcess(int32(check_pid))
v, err := ret.Ppid() v, err := ret.Ppid()
if err != nil { if err != nil {
t.Errorf("memory map get error %v", err) t.Errorf("geting ppid error %v", err)
} }
if v == 0 { if v == 0 {
t.Errorf("memory map get error %v", v) t.Errorf("return value is 0 %v", v)
} }
} }

@ -4,11 +4,9 @@ package gopsutil
import ( import (
"errors" "errors"
"fmt" "github.com/shirou/w32"
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/shirou/w32"
) )
const ( const (
@ -16,19 +14,6 @@ const (
MAX_PATH = 260 MAX_PATH = 260
) )
type PROCESSENTRY32 struct {
DwSize uint32
CntUsage uint32
Th32ProcessID uint32
Th32DefaultHeapID uintptr
Th32ModuleID uint32
CntThreads uint32
Th32ParentProcessID uint32
PcPriClassBase int32
DwFlags uint32
SzExeFile [MAX_PATH]uint16
}
type SYSTEM_PROCESS_INFORMATION struct { type SYSTEM_PROCESS_INFORMATION struct {
NextEntryOffset uint64 NextEntryOffset uint64
NumberOfThreads uint64 NumberOfThreads uint64
@ -67,104 +52,116 @@ func Pids() ([]int32, error) {
} }
func (p *Process) Ppid() (int32, error) { func (p *Process) Ppid() (int32, error) {
return 0, nil ret, _, _, err := p.getFromSnapProcess(p.Pid)
if err != nil {
return 0, err
}
return ret, nil
} }
func (p *Process) Name() (string, error) { func (p *Process) Name() (string, error) {
name := "" name := ""
return name, nil return name, errors.New("Not implemented yet")
} }
func (p *Process) Exe() (string, error) { func (p *Process) Exe() (string, error) {
return "", nil _, _, ret, err := p.getFromSnapProcess(p.Pid)
if err != nil {
return "", err
}
return ret, nil
} }
func (p *Process) Cmdline() (string, error) { func (p *Process) Cmdline() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
return p, nil return p, errors.New("Not implemented yet")
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Username() (string, error) { func (p *Process) Username() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Uids() ([]int32, error) { func (p *Process) Uids() ([]int32, error) {
uids := make([]int32, 0) uids := make([]int32, 0)
return uids, nil return uids, errors.New("Not implemented yet")
} }
func (p *Process) Gids() ([]int32, error) { func (p *Process) Gids() ([]int32, error) {
gids := make([]int32, 0) gids := make([]int32, 0)
return gids, nil return gids, errors.New("Not implemented yet")
} }
func (p *Process) Terminal() (string, error) { func (p *Process) Terminal() (string, error) {
return "", nil return "", errors.New("Not implemented yet")
} }
func (p *Process) Nice() (int32, error) { func (p *Process) Nice() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Ionice() (int32, error) { func (p *Process) Ionice() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Rlimit() ([]RlimitStat, error) { func (p *Process) Rlimit() ([]RlimitStat, error) {
rlimit := make([]RlimitStat, 0) rlimit := make([]RlimitStat, 0)
return rlimit, nil return rlimit, errors.New("Not implemented yet")
} }
func (p *Process) Io_counters() (*Io_countersStat, error) { func (p *Process) Io_counters() (*Io_countersStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Num_ctx_switches() (int32, error) { func (p *Process) Num_ctx_switches() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Num_fds() (int32, error) { func (p *Process) Num_fds() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Num_Threads() (int32, error) { func (p *Process) Num_Threads() (int32, error) {
return 0, nil _, ret, _, err := p.getFromSnapProcess(p.Pid)
if err != nil {
return 0, err
}
return ret, nil
} }
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, nil return ret, errors.New("Not implemented yet")
} }
func (p *Process) Cpu_times() (*CPU_TimesStat, error) { func (p *Process) Cpu_times() (*CPU_TimesStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Cpu_percent() (int32, error) { func (p *Process) Cpu_percent() (int32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Cpu_affinity() ([]int32, error) { func (p *Process) Cpu_affinity() ([]int32, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Memory_info() (*Memory_infoStat, error) { func (p *Process) Memory_info() (*Memory_infoStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Memory_info_ex() (*Memory_info_exStat, error) { func (p *Process) Memory_info_ex() (*Memory_info_exStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Memory_percent() (float32, error) { func (p *Process) Memory_percent() (float32, error) {
return 0, nil return 0, errors.New("Not implemented yet")
} }
func (p *Process) Children() ([]*Process, error) { func (p *Process) Children() ([]*Process, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Open_files() ([]Open_filesStat, error) { func (p *Process) Open_files() ([]Open_filesStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Connections() ([]Net_connectionStat, error) { func (p *Process) Connections() ([]Net_connectionStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func (p *Process) Is_running() (bool, error) { func (p *Process) Is_running() (bool, error) {
return true, nil return true, errors.New("Not implemented yet")
} }
func (p *Process) Memory_Maps() (*[]Memory_mapsStat, error) { func (p *Process) Memory_Maps(grouped bool) (*[]Memory_mapsStat, error) {
return nil, nil return nil, errors.New("Not implemented yet")
} }
func NewProcess(pid int32) (*Process, error) { func NewProcess(pid int32) (*Process, error) {
@ -174,51 +171,46 @@ func NewProcess(pid int32) (*Process, error) {
} }
func (p *Process) Send_signal(sig syscall.Signal) error { func (p *Process) Send_signal(sig syscall.Signal) error {
return nil return errors.New("Not implemented yet")
} }
func (p *Process) Suspend() error { func (p *Process) Suspend() error {
return nil return errors.New("Not implemented yet")
} }
func (p *Process) Resume() error { func (p *Process) Resume() error {
return nil return errors.New("Not implemented yet")
} }
func (p *Process) Terminate() error { func (p *Process) Terminate() error {
return nil return errors.New("Not implemented yet")
} }
func (p *Process) Kill() error { func (p *Process) Kill() error {
return nil return errors.New("Not implemented yet")
}
func copy_params(pe32 *PROCESSENTRY32, p *Process) error {
// p.Ppid = int32(pe32.Th32ParentProcessID)
return nil
}
func printModuleInfo(me32 *w32.MODULEENTRY32) {
fmt.Printf("Exe: %s\n", syscall.UTF16ToString(me32.SzExePath[:]))
} }
func printProcessInfo(pid uint32) error { func (p *Process) getFromSnapProcess(pid int32) (int32, int32, string, error) {
snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPMODULE, pid) snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(pid))
if snap == 0 { if snap == 0 {
return errors.New("snapshot could not be created") return 0, 0, "", syscall.GetLastError()
} }
defer w32.CloseHandle(snap) defer w32.CloseHandle(snap)
var pe32 w32.PROCESSENTRY32
var me32 w32.MODULEENTRY32 pe32.DwSize = uint32(unsafe.Sizeof(pe32))
me32.Size = uint32(unsafe.Sizeof(me32)) if w32.Process32First(snap, &pe32) == false {
if !w32.Module32First(snap, &me32) { return 0, 0, "", syscall.GetLastError()
return errors.New("module information retrieval failed")
} }
fmt.Printf("pid:%d\n", pid) if pe32.Th32ProcessID == uint32(pid) {
printModuleInfo(&me32) szexe := syscall.UTF16ToString(pe32.SzExeFile[:])
for w32.Module32Next(snap, &me32) { return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
printModuleInfo(&me32)
} }
return nil for w32.Process32Next(snap, &pe32) {
if pe32.Th32ProcessID == uint32(pid) {
szexe := syscall.UTF16ToString(pe32.SzExeFile[:])
return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
}
}
return 0, 0, "", errors.New("Cloud not find pid:" + string(pid))
} }
// Get processes // Get processes
@ -226,23 +218,20 @@ func processes() ([]*Process, error) {
ps := make([]uint32, 255) ps := make([]uint32, 255)
var read uint32 = 0 var read uint32 = 0
if w32.EnumProcesses(ps, uint32(len(ps)), &read) == false { if w32.EnumProcesses(ps, uint32(len(ps)), &read) == false {
println("could not read processes")
return nil, syscall.GetLastError() return nil, syscall.GetLastError()
} }
results := make([]*Process, 0) results := make([]*Process, 0)
for _, pid := range ps[:read/4] { dward_size := uint32(4)
for _, pid := range ps[:read/dward_size] {
if pid == 0 { if pid == 0 {
continue continue
} }
p, err := NewProcess(int32(pid)) p, err := NewProcess(int32(pid))
if err != nil { if err != nil {
break break
} }
results = append(results, p) results = append(results, p)
// printProcessInfo(pid)
} }
return results, nil return results, nil

Loading…
Cancel
Save