diff --git a/README.rst b/README.rst index 5b37ddf..a858ff0 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ gopsutil: psutil for golang :target: https://coveralls.io/r/shirou/gopsutil?branch=master -This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all +This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all psutil functions on some architectures... .. highlights:: Package Structure Changed! @@ -59,6 +59,7 @@ The output is below. Total: 3179569152, Free:284233728, UsedPercent:84.508194% {"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. Documentation ------------------------ @@ -178,7 +179,7 @@ suspend x x x resume x x x terminate x x x kill x x x -username x +username x ionice rlimit num_handlres @@ -204,7 +205,7 @@ hostname x x x x platform x x x platformfamiliy x x x virtualization x -**CPU** +**CPU** VendorID x x x x Family x x x x Model x x x x @@ -213,16 +214,16 @@ hostname x x x x CoreID x Cores x x ModelName x x x x -**LoadAvg** +**LoadAvg** Load1 x x x Load5 x x x Load15 x x x -**GetDockerID** +**GetDockerID** container id x no no no -**CgroupsCPU** +**CgroupsCPU** user x no no no system x no no no -**CgroupsMem** +**CgroupsMem** various x no no no ================== ===== ======= ====== ======= diff --git a/common/common.go b/common/common.go index a7dbc28..d04cdfd 100644 --- a/common/common.go +++ b/common/common.go @@ -207,3 +207,12 @@ func PathExists(filename string) bool { } return false } + +//GetEnv retreives the environment variable key. If it does not exist it returns the default. +func GetEnv(key string, dfault string) string { + value := os.Getenv(key) + if value == "" { + value = dfault + } + return value +} diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index 942ef0c..1bec8a7 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -25,7 +25,7 @@ func init() { } func CPUTimes(percpu bool) ([]CPUTimesStat, error) { - filename := "/proc/stat" + filename := common.GetEnv("HOST_PROC", "/proc") + "/stat" var lines = []string{} if percpu { var startIdx uint = 1 @@ -56,7 +56,7 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) { } func CPUInfo() ([]CPUInfoStat, error) { - filename := "/proc/cpuinfo" + filename := common.GetEnv("HOST_PROC", "/proc") + "cpuinfo" lines, _ := common.ReadLines(filename) var ret []CPUInfoStat diff --git a/disk/disk_linux.go b/disk/disk_linux.go index df59f6a..93f59b0 100644 --- a/disk/disk_linux.go +++ b/disk/disk_linux.go @@ -238,7 +238,7 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) { } func DiskIOCounters() (map[string]DiskIOCountersStat, error) { - filename := "/proc/diskstats" + filename := common.GetEnv("HOST_PROC", "/proc") + "/diskstats" lines, err := common.ReadLines(filename) if err != nil { return nil, err diff --git a/host/host_linux.go b/host/host_linux.go index 518987f..9131fa8 100644 --- a/host/host_linux.go +++ b/host/host_linux.go @@ -56,7 +56,8 @@ func HostInfo() (*HostInfoStat, error) { // BootTime returns the system boot time expressed in seconds since the epoch. func BootTime() (uint64, error) { - lines, err := common.ReadLines("/proc/stat") + filename := common.GetEnv("HOST_PROC", "/proc") + "/stat" + lines, err := common.ReadLines(filename) if err != nil { return 0, err } @@ -320,12 +321,13 @@ func GetVirtualization() (string, string, error) { var system string var role string - if common.PathExists("/proc/xen") { + filename := common.GetEnv("HOST_PROC", "/proc") + "/xen" + if common.PathExists(filename) { system = "xen" role = "guest" // assume guest - if common.PathExists("/proc/xen/capabilities") { - contents, err := common.ReadLines("/proc/xen/capabilities") + if common.PathExists(filename + "/capabilities") { + contents, err := common.ReadLines(filename + "/capabilities") if err == nil { if common.StringsHas(contents, "control_d") { role = "host" @@ -333,8 +335,10 @@ func GetVirtualization() (string, string, error) { } } } - if common.PathExists("/proc/modules") { - contents, err := common.ReadLines("/proc/modules") + + filename = common.GetEnv("HOST_PROC", "/proc") + "/modules" + if common.PathExists(filename) { + contents, err := common.ReadLines(filename) if err == nil { if common.StringsContains(contents, "kvm") { system = "kvm" @@ -349,8 +353,9 @@ func GetVirtualization() (string, string, error) { } } - if common.PathExists("/proc/cpuinfo") { - contents, err := common.ReadLines("/proc/cpuinfo") + filename = common.GetEnv("HOST_PROC", "/proc") + "/cpuinfo" + if common.PathExists(filename) { + contents, err := common.ReadLines(filename) if err == nil { if common.StringsHas(contents, "QEMU Virtual CPU") || common.StringsHas(contents, "Common KVM processor") || @@ -361,18 +366,18 @@ func GetVirtualization() (string, string, error) { } } - if common.PathExists("/proc/bc/0") { + filename = common.GetEnv("HOST_PROC", "/proc") + if common.PathExists(filename + "/bc/0") { system = "openvz" role = "host" - } else if common.PathExists("/proc/vz") { + } else if common.PathExists(filename + "/vz") { system = "openvz" role = "guest" } // not use dmidecode because it requires root - - if common.PathExists("/proc/self/status") { - contents, err := common.ReadLines("/proc/self/status") + if common.PathExists(filename + "/self/status") { + contents, err := common.ReadLines(filename + "/self/status") if err == nil { if common.StringsHas(contents, "s_context:") || @@ -383,8 +388,8 @@ func GetVirtualization() (string, string, error) { } } - if common.PathExists("/proc/self/cgroup") { - contents, err := common.ReadLines("/proc/self/cgroup") + if common.PathExists(filename + "/self/cgroup") { + contents, err := common.ReadLines(filename + "/self/cgroup") if err == nil { if common.StringsHas(contents, "lxc") || common.StringsHas(contents, "docker") { diff --git a/host/host_windows.go b/host/host_windows.go index eecbdf0..e8ba125 100644 --- a/host/host_windows.go +++ b/host/host_windows.go @@ -12,7 +12,7 @@ import ( "github.com/StackExchange/wmi" common "github.com/shirou/gopsutil/common" - process "github.com/shirou/gopsutil/process" + process "github.com/shirou/gopsutil/common/process" ) var ( @@ -43,6 +43,8 @@ func HostInfo() (*HostInfoStat, error) { ret.Platform = platform ret.PlatformFamily = family ret.PlatformVersion = version + } else { + return ret, err } ret.Uptime, err = BootTime() diff --git a/load/load_linux.go b/load/load_linux.go index 6c9926b..4ab5a96 100644 --- a/load/load_linux.go +++ b/load/load_linux.go @@ -6,10 +6,12 @@ import ( "io/ioutil" "strconv" "strings" + + common "github.com/shirou/gopsutil/common" ) func LoadAvg() (*LoadAvgStat, error) { - filename := "/proc/loadavg" + filename := common.GetEnv("HOST_PROC", "/proc") + "/loadavg" line, err := ioutil.ReadFile(filename) if err != nil { return nil, err diff --git a/mem/mem_linux.go b/mem/mem_linux.go index ccad5da..e45a084 100644 --- a/mem/mem_linux.go +++ b/mem/mem_linux.go @@ -11,7 +11,7 @@ import ( ) func VirtualMemory() (*VirtualMemoryStat, error) { - filename := "/proc/meminfo" + filename := common.GetEnv("HOST_PROC", "/proc") + "/meminfo" lines, _ := common.ReadLines(filename) // flag if MemAvailable is in /proc/meminfo (kernel 3.14+) memavail := false @@ -74,7 +74,8 @@ func SwapMemory() (*SwapMemoryStat, error) { } else { ret.UsedPercent = 0 } - lines, _ := common.ReadLines("/proc/vmstat") + filename := common.GetEnv("HOST_PROC", "/proc") + "/vmstat" + lines, _ := common.ReadLines(filename) for _, l := range lines { fields := strings.Fields(l) if len(fields) < 2 { diff --git a/net/net_linux.go b/net/net_linux.go index 9184439..73b2bee 100644 --- a/net/net_linux.go +++ b/net/net_linux.go @@ -15,7 +15,7 @@ import ( // every network interface installed on the system is returned // separately. func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { - filename := "/proc/net/dev" + filename := common.GetEnv("HOST_PROC", "/proc") + "/net/dev" lines, err := common.ReadLines(filename) if err != nil { return nil, err diff --git a/process/process_linux.go b/process/process_linux.go index 692329f..0d3a397 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -222,7 +222,7 @@ func (p *Process) IsRunning() (bool, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { pid := p.Pid var ret []MemoryMapsStat - smapsPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "smaps") + smapsPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "smaps") contents, err := ioutil.ReadFile(smapsPath) if err != nil { return nil, err @@ -303,7 +303,7 @@ func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { // Get num_fds from /proc/(pid)/fd func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) { pid := p.Pid - statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "fd") + statPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "fd") d, err := os.Open(statPath) if err != nil { return 0, nil, err @@ -336,7 +336,7 @@ func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) { // Get cwd from /proc/(pid)/cwd func (p *Process) fillFromCwd() (string, error) { pid := p.Pid - cwdPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "cwd") + cwdPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "cwd") cwd, err := os.Readlink(cwdPath) if err != nil { return "", err @@ -347,7 +347,7 @@ func (p *Process) fillFromCwd() (string, error) { // Get exe from /proc/(pid)/exe func (p *Process) fillFromExe() (string, error) { pid := p.Pid - exePath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "exe") + exePath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "exe") exe, err := os.Readlink(exePath) if err != nil { return "", err @@ -358,7 +358,7 @@ func (p *Process) fillFromExe() (string, error) { // Get cmdline from /proc/(pid)/cmdline func (p *Process) fillFromCmdline() (string, error) { pid := p.Pid - cmdPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "cmdline") + cmdPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "cmdline") cmdline, err := ioutil.ReadFile(cmdPath) if err != nil { return "", err @@ -376,7 +376,7 @@ func (p *Process) fillFromCmdline() (string, error) { // Get IO status from /proc/(pid)/io func (p *Process) fillFromIO() (*IOCountersStat, error) { pid := p.Pid - ioPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "io") + ioPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "io") ioline, err := ioutil.ReadFile(ioPath) if err != nil { return nil, err @@ -415,7 +415,7 @@ func (p *Process) fillFromIO() (*IOCountersStat, error) { // Get memory info from /proc/(pid)/statm func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) { pid := p.Pid - memPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "statm") + memPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "statm") contents, err := ioutil.ReadFile(memPath) if err != nil { return nil, nil, err @@ -467,7 +467,7 @@ func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) { // Get various status from /proc/(pid)/status func (p *Process) fillFromStatus() error { pid := p.Pid - statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "status") + statPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "status") contents, err := ioutil.ReadFile(statPath) if err != nil { return err @@ -554,7 +554,7 @@ func (p *Process) fillFromStatus() error { func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32, error) { pid := p.Pid - statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "stat") + statPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "stat") contents, err := ioutil.ReadFile(statPath) if err != nil { return "", 0, nil, 0, 0, err @@ -610,7 +610,7 @@ func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32 func Pids() ([]int32, error) { var ret []int32 - d, err := os.Open("/proc") + d, err := os.Open(common.GetEnv("HOST_PROC", "/proc")) if err != nil { return nil, err }