Skip to content

Commit 0461c50

Browse files
author
Jonathan Chauncey
committed
chore(*): Fixes shirou#94
Added the ability to fetch an alternative location for /proc via an environment variable. If the env var is not set it will return /proc as the default value.
1 parent 8f48da8 commit 0461c50

10 files changed

+60
-40
lines changed

README.rst

+8-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ gopsutil: psutil for golang
88
:target: https://coveralls.io/r/shirou/gopsutil?branch=master
99

1010

11-
This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all
11+
This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all
1212
psutil functions on some architectures...
1313

1414
.. highlights:: Package Structure Changed!
@@ -59,6 +59,7 @@ The output is below.
5959
Total: 3179569152, Free:284233728, UsedPercent:84.508194%
6060
{"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip)}
6161

62+
You can set an alternative location to /proc by setting the HOST_PROC environment variable.
6263

6364
Documentation
6465
------------------------
@@ -178,7 +179,7 @@ suspend x x x
178179
resume x x x
179180
terminate x x x
180181
kill x x x
181-
username x
182+
username x
182183
ionice
183184
rlimit
184185
num_handlres
@@ -204,7 +205,7 @@ hostname x x x x
204205
platform x x x
205206
platformfamiliy x x x
206207
virtualization x
207-
**CPU**
208+
**CPU**
208209
VendorID x x x x
209210
Family x x x x
210211
Model x x x x
@@ -213,16 +214,16 @@ hostname x x x x
213214
CoreID x
214215
Cores x x
215216
ModelName x x x x
216-
**LoadAvg**
217+
**LoadAvg**
217218
Load1 x x x
218219
Load5 x x x
219220
Load15 x x x
220-
**GetDockerID**
221+
**GetDockerID**
221222
container id x no no no
222-
**CgroupsCPU**
223+
**CgroupsCPU**
223224
user x no no no
224225
system x no no no
225-
**CgroupsMem**
226+
**CgroupsMem**
226227
various x no no no
227228
================== ===== ======= ====== =======
228229

common/common.go

+9
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,12 @@ func PathExists(filename string) bool {
207207
}
208208
return false
209209
}
210+
211+
//GetEnv retreives the environment variable key. If it does not exist it returns the default.
212+
func GetEnv(key string, dfault string) string {
213+
value := os.Getenv(key)
214+
if value == "" {
215+
value = dfault
216+
}
217+
return value
218+
}

cpu/cpu_linux.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func init() {
2525
}
2626

2727
func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
28-
filename := "/proc/stat"
28+
filename := common.GetEnv("HOST_PROC", "/proc") + "/stat"
2929
var lines = []string{}
3030
if percpu {
3131
var startIdx uint = 1
@@ -56,7 +56,7 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
5656
}
5757

5858
func CPUInfo() ([]CPUInfoStat, error) {
59-
filename := "/proc/cpuinfo"
59+
filename := common.GetEnv("HOST_PROC", "/proc") + "cpuinfo"
6060
lines, _ := common.ReadLines(filename)
6161

6262
var ret []CPUInfoStat

disk/disk_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
238238
}
239239

240240
func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
241-
filename := "/proc/diskstats"
241+
filename := common.GetEnv("HOST_PROC", "/proc") + "/diskstats"
242242
lines, err := common.ReadLines(filename)
243243
if err != nil {
244244
return nil, err

host/host_linux.go

+20-15
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ func HostInfo() (*HostInfoStat, error) {
5656

5757
// BootTime returns the system boot time expressed in seconds since the epoch.
5858
func BootTime() (uint64, error) {
59-
lines, err := common.ReadLines("/proc/stat")
59+
filename := common.GetEnv("HOST_PROC", "/proc") + "/stat"
60+
lines, err := common.ReadLines(filename)
6061
if err != nil {
6162
return 0, err
6263
}
@@ -320,21 +321,24 @@ func GetVirtualization() (string, string, error) {
320321
var system string
321322
var role string
322323

323-
if common.PathExists("/proc/xen") {
324+
filename := common.GetEnv("HOST_PROC", "/proc") + "/xen"
325+
if common.PathExists(filename) {
324326
system = "xen"
325327
role = "guest" // assume guest
326328

327-
if common.PathExists("/proc/xen/capabilities") {
328-
contents, err := common.ReadLines("/proc/xen/capabilities")
329+
if common.PathExists(filename + "/capabilities") {
330+
contents, err := common.ReadLines(filename + "/capabilities")
329331
if err == nil {
330332
if common.StringsHas(contents, "control_d") {
331333
role = "host"
332334
}
333335
}
334336
}
335337
}
336-
if common.PathExists("/proc/modules") {
337-
contents, err := common.ReadLines("/proc/modules")
338+
339+
filename = common.GetEnv("HOST_PROC", "/proc") + "/modules"
340+
if common.PathExists(filename) {
341+
contents, err := common.ReadLines(filename)
338342
if err == nil {
339343
if common.StringsContains(contents, "kvm") {
340344
system = "kvm"
@@ -349,8 +353,9 @@ func GetVirtualization() (string, string, error) {
349353
}
350354
}
351355

352-
if common.PathExists("/proc/cpuinfo") {
353-
contents, err := common.ReadLines("/proc/cpuinfo")
356+
filename = common.GetEnv("HOST_PROC", "/proc") + "/cpuinfo"
357+
if common.PathExists(filename) {
358+
contents, err := common.ReadLines(filename)
354359
if err == nil {
355360
if common.StringsHas(contents, "QEMU Virtual CPU") ||
356361
common.StringsHas(contents, "Common KVM processor") ||
@@ -361,18 +366,18 @@ func GetVirtualization() (string, string, error) {
361366
}
362367
}
363368

364-
if common.PathExists("/proc/bc/0") {
369+
filename = common.GetEnv("HOST_PROC", "/proc")
370+
if common.PathExists(filename + "/bc/0") {
365371
system = "openvz"
366372
role = "host"
367-
} else if common.PathExists("/proc/vz") {
373+
} else if common.PathExists(filename + "/vz") {
368374
system = "openvz"
369375
role = "guest"
370376
}
371377

372378
// not use dmidecode because it requires root
373-
374-
if common.PathExists("/proc/self/status") {
375-
contents, err := common.ReadLines("/proc/self/status")
379+
if common.PathExists(filename + "/self/status") {
380+
contents, err := common.ReadLines(filename + "/self/status")
376381
if err == nil {
377382

378383
if common.StringsHas(contents, "s_context:") ||
@@ -383,8 +388,8 @@ func GetVirtualization() (string, string, error) {
383388
}
384389
}
385390

386-
if common.PathExists("/proc/self/cgroup") {
387-
contents, err := common.ReadLines("/proc/self/cgroup")
391+
if common.PathExists(filename + "/self/cgroup") {
392+
contents, err := common.ReadLines(filename + "/self/cgroup")
388393
if err == nil {
389394
if common.StringsHas(contents, "lxc") ||
390395
common.StringsHas(contents, "docker") {

host/host_windows.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/StackExchange/wmi"
1313

1414
common "github.com/shirou/gopsutil/common"
15-
process "github.com/shirou/gopsutil/process"
15+
process "github.com/shirou/gopsutil/common/process"
1616
)
1717

1818
var (
@@ -43,6 +43,8 @@ func HostInfo() (*HostInfoStat, error) {
4343
ret.Platform = platform
4444
ret.PlatformFamily = family
4545
ret.PlatformVersion = version
46+
} else {
47+
return ret, err
4648
}
4749

4850
ret.Uptime, err = BootTime()

load/load_linux.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import (
66
"io/ioutil"
77
"strconv"
88
"strings"
9+
10+
common "github.com/shirou/gopsutil/common"
911
)
1012

1113
func LoadAvg() (*LoadAvgStat, error) {
12-
filename := "/proc/loadavg"
14+
filename := common.GetEnv("HOST_PROC", "/proc") + "/loadavg"
1315
line, err := ioutil.ReadFile(filename)
1416
if err != nil {
1517
return nil, err

mem/mem_linux.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
)
1212

1313
func VirtualMemory() (*VirtualMemoryStat, error) {
14-
filename := "/proc/meminfo"
14+
filename := common.GetEnv("HOST_PROC", "/proc") + "/meminfo"
1515
lines, _ := common.ReadLines(filename)
1616
// flag if MemAvailable is in /proc/meminfo (kernel 3.14+)
1717
memavail := false
@@ -74,7 +74,8 @@ func SwapMemory() (*SwapMemoryStat, error) {
7474
} else {
7575
ret.UsedPercent = 0
7676
}
77-
lines, _ := common.ReadLines("/proc/vmstat")
77+
filename := common.GetEnv("HOST_PROC", "/proc") + "/vmstat"
78+
lines, _ := common.ReadLines(filename)
7879
for _, l := range lines {
7980
fields := strings.Fields(l)
8081
if len(fields) < 2 {

net/net_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
// every network interface installed on the system is returned
1616
// separately.
1717
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
18-
filename := "/proc/net/dev"
18+
filename := common.GetEnv("HOST_PROC", "/proc") + "/net/dev"
1919
lines, err := common.ReadLines(filename)
2020
if err != nil {
2121
return nil, err

process/process_linux.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ func (p *Process) IsRunning() (bool, error) {
222222
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
223223
pid := p.Pid
224224
var ret []MemoryMapsStat
225-
smapsPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "smaps")
225+
smapsPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "smaps")
226226
contents, err := ioutil.ReadFile(smapsPath)
227227
if err != nil {
228228
return nil, err
@@ -303,7 +303,7 @@ func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
303303
// Get num_fds from /proc/(pid)/fd
304304
func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) {
305305
pid := p.Pid
306-
statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "fd")
306+
statPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "fd")
307307
d, err := os.Open(statPath)
308308
if err != nil {
309309
return 0, nil, err
@@ -336,7 +336,7 @@ func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) {
336336
// Get cwd from /proc/(pid)/cwd
337337
func (p *Process) fillFromCwd() (string, error) {
338338
pid := p.Pid
339-
cwdPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "cwd")
339+
cwdPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "cwd")
340340
cwd, err := os.Readlink(cwdPath)
341341
if err != nil {
342342
return "", err
@@ -347,7 +347,7 @@ func (p *Process) fillFromCwd() (string, error) {
347347
// Get exe from /proc/(pid)/exe
348348
func (p *Process) fillFromExe() (string, error) {
349349
pid := p.Pid
350-
exePath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "exe")
350+
exePath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "exe")
351351
exe, err := os.Readlink(exePath)
352352
if err != nil {
353353
return "", err
@@ -358,7 +358,7 @@ func (p *Process) fillFromExe() (string, error) {
358358
// Get cmdline from /proc/(pid)/cmdline
359359
func (p *Process) fillFromCmdline() (string, error) {
360360
pid := p.Pid
361-
cmdPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "cmdline")
361+
cmdPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "cmdline")
362362
cmdline, err := ioutil.ReadFile(cmdPath)
363363
if err != nil {
364364
return "", err
@@ -376,7 +376,7 @@ func (p *Process) fillFromCmdline() (string, error) {
376376
// Get IO status from /proc/(pid)/io
377377
func (p *Process) fillFromIO() (*IOCountersStat, error) {
378378
pid := p.Pid
379-
ioPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "io")
379+
ioPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "io")
380380
ioline, err := ioutil.ReadFile(ioPath)
381381
if err != nil {
382382
return nil, err
@@ -415,7 +415,7 @@ func (p *Process) fillFromIO() (*IOCountersStat, error) {
415415
// Get memory info from /proc/(pid)/statm
416416
func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) {
417417
pid := p.Pid
418-
memPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "statm")
418+
memPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "statm")
419419
contents, err := ioutil.ReadFile(memPath)
420420
if err != nil {
421421
return nil, nil, err
@@ -467,7 +467,7 @@ func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) {
467467
// Get various status from /proc/(pid)/status
468468
func (p *Process) fillFromStatus() error {
469469
pid := p.Pid
470-
statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "status")
470+
statPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "status")
471471
contents, err := ioutil.ReadFile(statPath)
472472
if err != nil {
473473
return err
@@ -554,7 +554,7 @@ func (p *Process) fillFromStatus() error {
554554

555555
func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32, error) {
556556
pid := p.Pid
557-
statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "stat")
557+
statPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "stat")
558558
contents, err := ioutil.ReadFile(statPath)
559559
if err != nil {
560560
return "", 0, nil, 0, 0, err
@@ -610,7 +610,7 @@ func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32
610610
func Pids() ([]int32, error) {
611611
var ret []int32
612612

613-
d, err := os.Open("/proc")
613+
d, err := os.Open(common.GetEnv("HOST_PROC", "/proc"))
614614
if err != nil {
615615
return nil, err
616616
}

0 commit comments

Comments
 (0)