Update gopsutil godep dependency. Dont use godep go build anymore

godep seems to have a problem when dependencies have `internal`
packages. So removing `godep go build` and `godep go test` from the
build process in favor of just checking out the correct revisions using
`godep restore` into the regular GOPATH.

This basically means that we are not actually using anything within the
Godeps directory except Godeps.json. I should probably make a separate
go dependency management system that does this.
This commit is contained in:
Cameron Sparr 2015-12-04 11:44:56 -07:00
parent 00a6dbbe97
commit e6517d4140
52 changed files with 762 additions and 218 deletions

37
Godeps/Godeps.json generated
View File

@ -167,50 +167,45 @@
"ImportPath": "github.com/samuel/go-zookeeper/zk",
"Rev": "5bb5cfc093ad18a28148c578f8632cfdb4d802e4"
},
{
"ImportPath": "github.com/shirou/gopsutil/common",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
},
{
"ImportPath": "github.com/shirou/gopsutil/cpu",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/shirou/gopsutil/disk",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/shirou/gopsutil/docker",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/shirou/gopsutil/host",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/shirou/gopsutil/load",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/shirou/gopsutil/mem",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/shirou/gopsutil/net",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/shirou/gopsutil/process",
"Comment": "1.0.0-173-g1e9aabb",
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
"Comment": "1.0.0-208-g759e96e",
"Rev": "759e96ebaffb01c3cba0e8b129ef29f56507b323"
},
{
"ImportPath": "github.com/streadway/amqp",

View File

@ -3,7 +3,7 @@
package cpu
import "github.com/shirou/gopsutil/common"
import "github.com/shirou/gopsutil/internal/common"
func perCPUTimes() ([]CPUTimesStat, error) {
return []CPUTimesStat{}, common.NotImplementedError

View File

@ -9,7 +9,7 @@ import (
"strconv"
"strings"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
// sys/resource.h

View File

@ -4,11 +4,12 @@ package cpu
import (
"errors"
"fmt"
"os/exec"
"strconv"
"strings"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
var cpu_tick = float64(100)
@ -25,7 +26,7 @@ func init() {
}
func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
filename := common.GetEnv("HOST_PROC", "/proc") + "/stat"
filename := common.HostProc("stat")
var lines = []string{}
if percpu {
var startIdx uint = 1
@ -55,19 +56,47 @@ func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
return ret, nil
}
func sysCpuPath(cpu int32, relPath string) string {
return common.HostSys(fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath)
}
func finishCPUInfo(c *CPUInfoStat) error {
if c.Mhz == 0 {
lines, err := common.ReadLines(sysCpuPath(c.CPU, "cpufreq/cpuinfo_max_freq"))
if err == nil {
value, err := strconv.ParseFloat(lines[0], 64)
if err != nil {
return err
}
c.Mhz = value
}
}
if len(c.CoreID) == 0 {
lines, err := common.ReadLines(sysCpuPath(c.CPU, "topology/core_id"))
if err == nil {
c.CoreID = lines[0]
}
}
return nil
}
// CPUInfo on linux will return 1 item per physical thread.
//
// CPUs have three levels of counting: sockets, cores, threads.
// Cores with HyperThreading count as having 2 threads per core.
// Sockets often come with many physical CPU cores.
// For example a single socket board with two cores each with HT will
// return 4 CPUInfoStat structs on Linux and the "Cores" field set to 1.
func CPUInfo() ([]CPUInfoStat, error) {
filename := common.GetEnv("HOST_PROC", "/proc") + "cpuinfo"
filename := common.HostProc("cpuinfo")
lines, _ := common.ReadLines(filename)
var ret []CPUInfoStat
var c CPUInfoStat
c := CPUInfoStat{CPU: -1, Cores: 1}
for _, line := range lines {
fields := strings.Split(line, ":")
if len(fields) < 2 {
if c.VendorID != "" {
ret = append(ret, c)
}
continue
}
key := strings.TrimSpace(fields[0])
@ -75,7 +104,14 @@ func CPUInfo() ([]CPUInfoStat, error) {
switch key {
case "processor":
c = CPUInfoStat{}
if c.CPU >= 0 {
err := finishCPUInfo(&c)
if err != nil {
return ret, err
}
ret = append(ret, c)
}
c = CPUInfoStat{Cores: 1}
t, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return ret, err
@ -111,15 +147,18 @@ func CPUInfo() ([]CPUInfoStat, error) {
c.PhysicalID = value
case "core id":
c.CoreID = value
case "cpu cores":
t, err := strconv.ParseInt(value, 10, 64)
case "flags", "Features":
c.Flags = strings.FieldsFunc(value, func(r rune) bool {
return r == ',' || r == ' '
})
}
}
if c.CPU >= 0 {
err := finishCPUInfo(&c)
if err != nil {
return ret, err
}
c.Cores = int32(t)
case "flags":
c.Flags = strings.Split(value, ",")
}
ret = append(ret, c)
}
return ret, nil
}

View File

@ -82,7 +82,8 @@ func testCPUPercent(t *testing.T, percpu bool) {
t.Errorf("error %v", err)
}
for _, percent := range v {
if percent < 0.0 || percent > 100.0*float64(numcpu) {
// Check for slightly greater then 100% to account for any rounding issues.
if percent < 0.0 || percent > 100.0001*float64(numcpu) {
t.Fatalf("CPUPercent value is invalid: %f", percent)
}
}

View File

@ -10,7 +10,7 @@ import (
"github.com/StackExchange/wmi"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
type Win32_Processor struct {

View File

@ -6,7 +6,7 @@ import (
"syscall"
"unsafe"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func DiskPartitions(all bool) ([]DiskPartitionStat, error) {

View File

@ -9,7 +9,7 @@ import (
"syscall"
"unsafe"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
const (

View File

@ -0,0 +1,108 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_freebsd.go
package disk
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeofLongDouble = 0x8
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
MNT_RDONLY = 0x00000001
MNT_SYNCHRONOUS = 0x00000002
MNT_NOEXEC = 0x00000004
MNT_NOSUID = 0x00000008
MNT_UNION = 0x00000020
MNT_ASYNC = 0x00000040
MNT_SUIDDIR = 0x00100000
MNT_SOFTDEP = 0x00200000
MNT_NOSYMFOLLOW = 0x00400000
MNT_GJOURNAL = 0x02000000
MNT_MULTILABEL = 0x04000000
MNT_ACLS = 0x08000000
MNT_NOATIME = 0x10000000
MNT_NOCLUSTERR = 0x40000000
MNT_NOCLUSTERW = 0x80000000
MNT_NFS4ACLS = 0x00000010
MNT_WAIT = 1
MNT_NOWAIT = 2
MNT_LAZY = 3
MNT_SUSPEND = 4
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
_C_long_double int64
)
type Statfs struct {
Version uint32
Type uint32
Flags uint64
Bsize uint64
Iosize uint64
Blocks uint64
Bfree uint64
Bavail int64
Files uint64
Ffree int64
Syncwrites uint64
Asyncwrites uint64
Syncreads uint64
Asyncreads uint64
Spare [10]uint64
Namemax uint32
Owner uint32
Fsid Fsid
Charspare [80]int8
Fstypename [16]int8
Mntfromname [88]int8
Mntonname [88]int8
}
type Fsid struct {
Val [2]int32
}
type Devstat struct {
Sequence0 uint32
Allocated int32
Start_count uint32
End_count uint32
Busy_from Bintime
Dev_links _Ctype_struct___0
Device_number uint32
Device_name [16]int8
Unit_number int32
Bytes [4]uint64
Operations [4]uint64
Duration [4]Bintime
Busy_time Bintime
Creation_time Bintime
Block_size uint32
Tag_types [3]uint64
Flags uint32
Device_type uint32
Priority uint32
Id *byte
Sequence1 uint32
}
type Bintime struct {
Sec int32
Frac uint64
}
type _Ctype_struct___0 struct {
Empty uint32
}

View File

@ -9,7 +9,7 @@ import (
"strings"
"syscall"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
const (
@ -238,7 +238,7 @@ func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
}
func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
filename := common.GetEnv("HOST_PROC", "/proc") + "/diskstats"
filename := common.HostProc("diskstats")
lines, err := common.ReadLines(filename)
if err != nil {
return nil, err

View File

@ -16,7 +16,7 @@ func DiskUsage(path string) (*DiskUsageStat, error) {
Path: path,
Fstype: getFsType(stat),
Total: (uint64(stat.Blocks) * uint64(bsize)),
Free: (uint64(stat.Bfree) * uint64(bsize)),
Free: (uint64(stat.Bavail) * uint64(bsize)),
InodesTotal: (uint64(stat.Files)),
InodesFree: (uint64(stat.Ffree)),
}

View File

@ -9,7 +9,7 @@ import (
"github.com/StackExchange/wmi"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
var (

View File

@ -34,4 +34,8 @@ type CgroupMemStat struct {
TotalInactiveFile uint64 `json:"total_inactive_file"`
TotalActiveFile uint64 `json:"total_active_file"`
TotalUnevictable uint64 `json:"total_unevictable"`
MemUsageInBytes uint64 `json:"mem_usage_in_bytes"`
MemMaxUsageInBytes uint64 `json:"mem_max_usage_in_bytes"`
MemLimitInBytes uint64 `json:"memory.limit_in_bytes"`
MemFailCnt uint64 `json:"memory.failcnt"`
}

View File

@ -4,14 +4,15 @@ package docker
import (
"encoding/json"
"fmt"
"os"
"os/exec"
"path"
"strconv"
"strings"
common "github.com/shirou/gopsutil/common"
cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
)
// GetDockerIDList returnes a list of DockerID.
@ -40,28 +41,20 @@ func GetDockerIDList() ([]string, error) {
}
// CgroupCPU returnes specified cgroup id CPU status.
// containerid is same as docker id if you use docker.
// containerId is same as docker id if you use docker.
// If you use container via systemd.slice, you could use
// containerid = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
func CgroupCPU(containerid string, base string) (*cpu.CPUTimesStat, error) {
if len(base) == 0 {
base = "/sys/fs/cgroup/cpuacct/docker"
}
statfile := path.Join(base, containerid, "cpuacct.stat")
if _, err := os.Stat(statfile); os.IsNotExist(err) {
statfile = path.Join("/sys/fs/cgroup/cpuacct/system.slice", "docker-" + containerid + ".scope", "cpuacct.stat")
}
// containerId = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
func CgroupCPU(containerId string, base string) (*cpu.CPUTimesStat, error) {
statfile := getCgroupFilePath(containerId, base, "cpuacct", "cpuacct.stat")
lines, err := common.ReadLines(statfile)
if err != nil {
return nil, err
}
// empty containerid means all cgroup
if len(containerid) == 0 {
containerid = "all"
// empty containerId means all cgroup
if len(containerId) == 0 {
containerId = "all"
}
ret := &cpu.CPUTimesStat{CPU: containerid}
ret := &cpu.CPUTimesStat{CPU: containerId}
for _, line := range lines {
fields := strings.Split(line, " ")
if fields[0] == "user" {
@ -82,28 +75,21 @@ func CgroupCPU(containerid string, base string) (*cpu.CPUTimesStat, error) {
}
func CgroupCPUDocker(containerid string) (*cpu.CPUTimesStat, error) {
return CgroupCPU(containerid, "/sys/fs/cgroup/cpuacct/docker")
return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
}
func CgroupMem(containerid string, base string) (*CgroupMemStat, error) {
if len(base) == 0 {
base = "/sys/fs/cgroup/memory/docker"
}
statfile := path.Join(base, containerid, "memory.stat")
func CgroupMem(containerId string, base string) (*CgroupMemStat, error) {
statfile := getCgroupFilePath(containerId, base, "memory", "memory.stat")
if _, err := os.Stat(statfile); os.IsNotExist(err) {
statfile = path.Join("/sys/fs/cgroup/memory/system.slice", "docker-" + containerid + ".scope", "memory.stat")
}
// empty containerid means all cgroup
if len(containerid) == 0 {
containerid = "all"
// empty containerId means all cgroup
if len(containerId) == 0 {
containerId = "all"
}
lines, err := common.ReadLines(statfile)
if err != nil {
return nil, err
}
ret := &CgroupMemStat{ContainerID: containerid}
ret := &CgroupMemStat{ContainerID: containerId}
for _, line := range lines {
fields := strings.Split(line, " ")
v, err := strconv.ParseUint(fields[1], 10, 64)
@ -167,14 +153,61 @@ func CgroupMem(containerid string, base string) (*CgroupMemStat, error) {
ret.TotalUnevictable = v
}
}
r, err := getCgroupMemFile(containerId, base, "memory.usage_in_bytes")
if err == nil {
ret.MemUsageInBytes = r
}
r, err = getCgroupMemFile(containerId, base, "memory.max_usage_in_bytes")
if err == nil {
ret.MemMaxUsageInBytes = r
}
r, err = getCgroupMemFile(containerId, base, "memory.limit_in_bytes")
if err == nil {
ret.MemLimitInBytes = r
}
r, err = getCgroupMemFile(containerId, base, "memory.failcnt")
if err == nil {
ret.MemFailCnt = r
}
return ret, nil
}
func CgroupMemDocker(containerid string) (*CgroupMemStat, error) {
return CgroupMem(containerid, "/sys/fs/cgroup/memory/docker")
func CgroupMemDocker(containerId string) (*CgroupMemStat, error) {
return CgroupMem(containerId, common.HostSys("fs/cgroup/memory/docker"))
}
func (m CgroupMemStat) String() string {
s, _ := json.Marshal(m)
return string(s)
}
// getCgroupFilePath constructs file path to get targetted stats file.
func getCgroupFilePath(containerId, base, target, file string) string {
if len(base) == 0 {
base = common.HostSys(fmt.Sprintf("fs/cgroup/%s/docker", target))
}
statfile := path.Join(base, containerId, file)
if _, err := os.Stat(statfile); os.IsNotExist(err) {
statfile = path.Join(
common.HostSys(fmt.Sprintf("fs/cgroup/%s/system.slice", target)), "docker-"+containerId+".scope", file)
}
return statfile
}
// getCgroupMemFile reads a cgroup file and return the contents as uint64.
func getCgroupMemFile(containerId, base, file string) (uint64, error) {
statfile := getCgroupFilePath(containerId, base, "memory", file)
lines, err := common.ReadLines(statfile)
if err != nil {
return 0, err
}
if len(lines) != 1 {
return 0, fmt.Errorf("wrong format file: %s", statfile)
}
return strconv.ParseUint(lines[0], 10, 64)
}

View File

@ -2,9 +2,7 @@
package docker
import (
"testing"
)
import "testing"
func TestGetDockerIDList(t *testing.T) {
// If there is not docker environment, this test always fail.

View File

@ -6,6 +6,7 @@ import (
"encoding/json"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
)
// GetDockerIDList returnes a list of DockerID.
@ -23,7 +24,7 @@ func CgroupCPU(containerid string, base string) (*cpu.CPUTimesStat, error) {
}
func CgroupCPUDocker(containerid string) (*cpu.CPUTimesStat, error) {
return CgroupCPU(containerid, "/sys/fs/cgroup/cpuacct/docker")
return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
}
func CgroupMem(containerid string, base string) (*CgroupMemStat, error) {
@ -31,7 +32,7 @@ func CgroupMem(containerid string, base string) (*CgroupMemStat, error) {
}
func CgroupMemDocker(containerid string) (*CgroupMemStat, error) {
return CgroupMem(containerid, "/sys/fs/cgroup/memory/docker")
return CgroupMem(containerid, common.HostSys("fs/cgroup/memory/docker"))
}
func (m CgroupMemStat) String() string {

View File

@ -9,6 +9,7 @@ import (
type HostInfoStat struct {
Hostname string `json:"hostname"`
Uptime uint64 `json:"uptime"`
BootTime uint64 `json:"boot_time"`
Procs uint64 `json:"procs"` // number of processes
OS string `json:"os"` // ex: freebsd, linux
Platform string `json:"platform"` // ex: ubuntu, linuxmint

View File

@ -11,9 +11,10 @@ import (
"runtime"
"strconv"
"strings"
"time"
"unsafe"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func HostInfo() (*HostInfoStat, error) {
@ -39,14 +40,10 @@ func HostInfo() (*HostInfoStat, error) {
ret.VirtualizationRole = role
}
values, err := common.DoSysctrl("kern.boottime")
boot, err := BootTime()
if err == nil {
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
v := strings.Replace(values[2], ",", "", 1)
t, err := strconv.ParseUint(v, 10, 64)
if err != nil {
ret.Uptime = t
}
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
return ret, nil
@ -59,7 +56,6 @@ func BootTime() (uint64, error) {
}
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
v := strings.Replace(values[2], ",", "", 1)
boottime, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return 0, err
@ -68,6 +64,18 @@ func BootTime() (uint64, error) {
return uint64(boottime), nil
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func Users() ([]UserStat, error) {
utmpfile := "/var/run/utmpx"
var ret []UserStat

View File

@ -11,9 +11,10 @@ import (
"runtime"
"strconv"
"strings"
"time"
"unsafe"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
const (
@ -45,20 +46,16 @@ func HostInfo() (*HostInfoStat, error) {
ret.VirtualizationRole = role
}
values, err := common.DoSysctrl("kern.boottime")
boot, err := BootTime()
if err == nil {
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
v := strings.Replace(values[2], ",", "", 1)
t, err := strconv.ParseUint(v, 10, 64)
if err == nil {
ret.Uptime = t
}
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
return ret, nil
}
func BootTime() (int64, error) {
func BootTime() (uint64, error) {
values, err := common.DoSysctrl("kern.boottime")
if err != nil {
return 0, err
@ -66,7 +63,7 @@ func BootTime() (int64, error) {
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
v := strings.Replace(values[2], ",", "", 1)
boottime, err := strconv.ParseInt(v, 10, 64)
boottime, err := strconv.ParseUint(v, 10, 64)
if err != nil {
return 0, err
}
@ -74,6 +71,18 @@ func BootTime() (int64, error) {
return boottime, nil
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func Users() ([]UserStat, error) {
utmpfile := "/var/run/utx.active"
if !common.PathExists(utmpfile) {

View File

@ -13,9 +13,10 @@ import (
"runtime"
"strconv"
"strings"
"time"
"unsafe"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
type LSB struct {
@ -46,9 +47,10 @@ func HostInfo() (*HostInfoStat, error) {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
uptime, err := BootTime()
boot, err := BootTime()
if err == nil {
ret.Uptime = uptime
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
return ret, nil
@ -56,7 +58,7 @@ func HostInfo() (*HostInfoStat, error) {
// BootTime returns the system boot time expressed in seconds since the epoch.
func BootTime() (uint64, error) {
filename := common.GetEnv("HOST_PROC", "/proc") + "/stat"
filename := common.HostProc("stat")
lines, err := common.ReadLines(filename)
if err != nil {
return 0, err
@ -78,6 +80,18 @@ func BootTime() (uint64, error) {
return 0, fmt.Errorf("could not find btime")
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func Users() ([]UserStat, error) {
utmpfile := "/var/run/utmp"
@ -321,7 +335,7 @@ func GetVirtualization() (string, string, error) {
var system string
var role string
filename := common.GetEnv("HOST_PROC", "/proc") + "/xen"
filename := common.HostProc("xen")
if common.PathExists(filename) {
system = "xen"
role = "guest" // assume guest
@ -336,7 +350,7 @@ func GetVirtualization() (string, string, error) {
}
}
filename = common.GetEnv("HOST_PROC", "/proc") + "/modules"
filename = common.HostProc("modules")
if common.PathExists(filename) {
contents, err := common.ReadLines(filename)
if err == nil {
@ -353,7 +367,7 @@ func GetVirtualization() (string, string, error) {
}
}
filename = common.GetEnv("HOST_PROC", "/proc") + "/cpuinfo"
filename = common.HostProc("cpuinfo")
if common.PathExists(filename) {
contents, err := common.ReadLines(filename)
if err == nil {
@ -366,7 +380,7 @@ func GetVirtualization() (string, string, error) {
}
}
filename = common.GetEnv("HOST_PROC", "/proc")
filename = common.HostProc()
if common.PathExists(filename + "/bc/0") {
system = "openvz"
role = "host"

View File

@ -46,8 +46,9 @@ func TestHostInfoStat_String(t *testing.T) {
Procs: 100,
OS: "linux",
Platform: "ubuntu",
BootTime: 1447040000,
}
e := `{"hostname":"test","uptime":3000,"procs":100,"os":"linux","platform":"ubuntu","platform_family":"","platform_version":"","virtualization_system":"","virtualization_role":""}`
e := `{"hostname":"test","uptime":3000,"boot_time":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platform_family":"","platform_version":"","virtualization_system":"","virtualization_role":""}`
if e != fmt.Sprintf("%v", v) {
t.Errorf("HostInfoStat string is invalid: %v", v)
}

View File

@ -11,8 +11,8 @@ import (
"github.com/StackExchange/wmi"
common "github.com/shirou/gopsutil/common"
process "github.com/shirou/gopsutil/common/process"
"github.com/shirou/gopsutil/internal/common"
process "github.com/shirou/gopsutil/process"
)
var (
@ -47,9 +47,10 @@ func HostInfo() (*HostInfoStat, error) {
return ret, err
}
ret.Uptime, err = BootTime()
if err != nil {
return ret, err
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
procs, err := process.Pids()
@ -87,6 +88,18 @@ func BootTime() (uint64, error) {
return uint64(now.Sub(t).Seconds()), nil
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func GetPlatformInformation() (platform string, family string, version string, err error) {
if osInfo == nil {
_, err = GetOSInfo()

View File

@ -5,7 +5,7 @@ package load
import (
"strconv"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func LoadAvg() (*LoadAvgStat, error) {

View File

@ -5,7 +5,7 @@ package load
import (
"strconv"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func LoadAvg() (*LoadAvgStat, error) {

View File

@ -7,11 +7,11 @@ import (
"strconv"
"strings"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func LoadAvg() (*LoadAvgStat, error) {
filename := common.GetEnv("HOST_PROC", "/proc") + "/loadavg"
filename := common.HostProc("loadavg")
line, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err

View File

@ -3,7 +3,7 @@
package load
import (
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func LoadAvg() (*LoadAvgStat, error) {

View File

@ -7,7 +7,7 @@ import (
"strconv"
"strings"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func getPageSize() (uint64, error) {

View File

@ -6,8 +6,8 @@ import (
"os/exec"
"strconv"
"strings"
common "github.com/shirou/gopsutil/common"
"errors"
"github.com/shirou/gopsutil/internal/common"
)
func VirtualMemory() (*VirtualMemoryStat, error) {
@ -91,7 +91,6 @@ func SwapMemory() (*SwapMemoryStat, error) {
if err != nil {
return nil, err
}
var ret *SwapMemoryStat
for _, line := range strings.Split(string(out), "\n") {
values := strings.Fields(line)
// skip title line
@ -117,13 +116,13 @@ func SwapMemory() (*SwapMemoryStat, error) {
return nil, err
}
ret = &SwapMemoryStat{
return &SwapMemoryStat{
Total: total_v,
Used: used_v,
Free: free_v,
UsedPercent: up_v,
}
}, nil
}
return ret, nil
return nil, errors.New("no swap devices found")
}

View File

@ -7,11 +7,11 @@ import (
"strings"
"syscall"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func VirtualMemory() (*VirtualMemoryStat, error) {
filename := common.GetEnv("HOST_PROC", "/proc") + "/meminfo"
filename := common.HostProc("meminfo")
lines, _ := common.ReadLines(filename)
// flag if MemAvailable is in /proc/meminfo (kernel 3.14+)
memavail := false
@ -74,7 +74,7 @@ func SwapMemory() (*SwapMemoryStat, error) {
} else {
ret.UsedPercent = 0
}
filename := common.GetEnv("HOST_PROC", "/proc") + "/vmstat"
filename := common.HostProc("vmstat")
lines, _ := common.ReadLines(filename)
for _, l := range lines {
fields := strings.Fields(l)

View File

@ -6,7 +6,7 @@ import (
"syscall"
"unsafe"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
var (

View File

@ -8,7 +8,7 @@ import (
"strings"
"syscall"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
var invoke common.Invoker
@ -45,6 +45,12 @@ type NetConnectionStat struct {
Pid int32 `json:"pid"`
}
// System wide stats about different network protocols
type NetProtoCountersStat struct {
Protocol string `json:"protocol"`
Stats map[string]int64 `json:"stats"`
}
// NetInterfaceAddr is designed for represent interface addresses
type NetInterfaceAddr struct {
Addr string `json:"addr"`
@ -75,6 +81,11 @@ func (n NetConnectionStat) String() string {
return string(s)
}
func (n NetProtoCountersStat) String() string {
s, _ := json.Marshal(n)
return string(s)
}
func (a Addr) String() string {
s, _ := json.Marshal(a)
return string(s)

View File

@ -3,11 +3,12 @@
package net
import (
"errors"
"os/exec"
"strconv"
"strings"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
// example of netstat -idbn output on yosemite
@ -90,3 +91,11 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
return ret, nil
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for Darwin
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for darwin")
}

View File

@ -3,11 +3,12 @@
package net
import (
"errors"
"os/exec"
"strconv"
"strings"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
@ -81,3 +82,11 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
return ret, nil
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for FreeBSD
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for freebsd")
}

View File

@ -3,10 +3,11 @@
package net
import (
"errors"
"strconv"
"strings"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
// NetIOCounters returnes network I/O statistics for every network
@ -15,7 +16,7 @@ import (
// every network interface installed on the system is returned
// separately.
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
filename := common.GetEnv("HOST_PROC", "/proc") + "/net/dev"
filename := common.HostProc("net/dev")
lines, err := common.ReadLines(filename)
if err != nil {
return nil, err
@ -89,3 +90,73 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
return ret, nil
}
var netProtocols = []string{
"ip",
"icmp",
"icmpmsg",
"tcp",
"udp",
"udplite",
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Available protocols:
// ip,icmp,icmpmsg,tcp,udp,udplite
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) {
if len(protocols) == 0 {
protocols = netProtocols
}
stats := make([]NetProtoCountersStat, 0, len(protocols))
protos := make(map[string]bool, len(protocols))
for _, p := range protocols {
protos[p] = true
}
filename := "/proc/net/snmp"
lines, err := common.ReadLines(filename)
if err != nil {
return nil, err
}
linecount := len(lines)
for i := 0; i < linecount; i++ {
line := lines[i]
r := strings.IndexRune(line, ':')
if r == -1 {
return nil, errors.New(filename + " is not fomatted correctly, expected ':'.")
}
proto := strings.ToLower(line[:r])
if !protos[proto] {
// skip protocol and data line
i++
continue
}
// Read header line
statNames := strings.Split(line[r+2:], " ")
// Read data line
i++
statValues := strings.Split(lines[i][r+2:], " ")
if len(statNames) != len(statValues) {
return nil, errors.New(filename + " is not fomatted correctly, expected same number of columns.")
}
stat := NetProtoCountersStat{
Protocol: proto,
Stats: make(map[string]int64, len(statNames)),
}
for j := range statNames {
value, err := strconv.ParseInt(statValues[j], 10, 64)
if err != nil {
return nil, err
}
stat.Stats[statNames[j]] = value
}
stats = append(stats, stat)
}
return stats, nil
}

View File

@ -26,6 +26,22 @@ func TestNetIOCountersStatString(t *testing.T) {
}
}
func TestNetProtoCountersStatString(t *testing.T) {
v := NetProtoCountersStat{
Protocol: "tcp",
Stats: map[string]int64{
"MaxConn": -1,
"ActiveOpens": 4000,
"PassiveOpens": 3000,
},
}
e := `{"protocol":"tcp","stats":{"ActiveOpens":4000,"MaxConn":-1,"PassiveOpens":3000}}`
if e != fmt.Sprintf("%v", v) {
t.Errorf("NetProtoCountersStat string is invalid: %v", v)
}
}
func TestNetConnectionStatString(t *testing.T) {
v := NetConnectionStat{
Fd: 10,
@ -122,6 +138,45 @@ func TestNetInterfaces(t *testing.T) {
}
}
func TestNetProtoCountersStatsAll(t *testing.T) {
v, err := NetProtoCounters(nil)
if err != nil {
t.Fatalf("Could not get NetProtoCounters: %v", err)
}
if len(v) == 0 {
t.Fatalf("Could not get NetProtoCounters: %v", err)
}
for _, vv := range v {
if vv.Protocol == "" {
t.Errorf("Invalid NetProtoCountersStat: %v", vv)
}
if len(vv.Stats) == 0 {
t.Errorf("Invalid NetProtoCountersStat: %v", vv)
}
}
}
func TestNetProtoCountersStats(t *testing.T) {
v, err := NetProtoCounters([]string{"tcp", "ip"})
if err != nil {
t.Fatalf("Could not get NetProtoCounters: %v", err)
}
if len(v) == 0 {
t.Fatalf("Could not get NetProtoCounters: %v", err)
}
if len(v) != 2 {
t.Fatalf("Go incorrect number of NetProtoCounters: %v", err)
}
for _, vv := range v {
if vv.Protocol != "tcp" && vv.Protocol != "ip" {
t.Errorf("Invalid NetProtoCountersStat: %v", vv)
}
if len(vv.Stats) == 0 {
t.Errorf("Invalid NetProtoCountersStat: %v", vv)
}
}
}
func TestNetConnections(t *testing.T) {
if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io
return

View File

@ -5,7 +5,7 @@ package net
import (
"strings"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
// Return a list of network connections opened.

View File

@ -3,12 +3,13 @@
package net
import (
"errors"
"net"
"os"
"syscall"
"unsafe"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
var (
@ -96,3 +97,11 @@ func getAdapterList() (*syscall.IpAdapterInfo, error) {
}
return a, nil
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for Windows
func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for windows")
}

View File

@ -5,8 +5,8 @@ import (
"runtime"
"time"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
)
var invoke common.Invoker

View File

@ -10,8 +10,8 @@ import (
"syscall"
"unsafe"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/net"
)
@ -278,7 +278,19 @@ func (p *Process) MemoryPercent() (float32, error) {
}
func (p *Process) Children() ([]*Process, error) {
return nil, common.NotImplementedError
pids, err := common.CallPgrep(invoke, p.Pid)
if err != nil {
return nil, err
}
ret := make([]*Process, 0, len(pids))
for _, pid := range pids {
np, err := NewProcess(pid)
if err != nil {
return nil, err
}
ret = append(ret, np)
}
return ret, nil
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {

View File

@ -6,9 +6,11 @@ import (
"bytes"
"encoding/binary"
"unsafe"
"strings"
"syscall"
common "github.com/shirou/gopsutil/common"
cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
net "github.com/shirou/gopsutil/net"
)
@ -53,7 +55,19 @@ func (p *Process) Exe() (string, error) {
return "", common.NotImplementedError
}
func (p *Process) Cmdline() (string, error) {
return "", common.NotImplementedError
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return "", err
}
ret := strings.FieldsFunc(string(buf), func(r rune) bool {
if r == '\u0000' {
return true
}
return false
})
return strings.Join(ret, " "), nil
}
func (p *Process) CreateTime() (int64, error) {
return 0, common.NotImplementedError
@ -121,7 +135,14 @@ func (p *Process) Rlimit() ([]RlimitStat, error) {
return rlimit, common.NotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return nil, common.NotImplementedError
k, err := p.getKProc()
if err != nil {
return nil, err
}
return &IOCountersStat{
ReadCount: uint64(k.KiRusage.Inblock),
WriteCount: uint64(k.KiRusage.Oublock),
}, nil
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return nil, common.NotImplementedError
@ -142,7 +163,15 @@ func (p *Process) Threads() (map[string]string, error) {
return ret, common.NotImplementedError
}
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
return nil, common.NotImplementedError
k, err := p.getKProc()
if err != nil {
return nil, err
}
return &cpu.CPUTimesStat{
CPU: "cpu",
User: float64(k.KiRusage.Utime.Sec) + float64(k.KiRusage.Utime.Usec)/1000000,
System: float64(k.KiRusage.Stime.Sec) + float64(k.KiRusage.Stime.Usec)/1000000,
}, nil
}
func (p *Process) CPUAffinity() ([]int32, error) {
return nil, common.NotImplementedError
@ -152,13 +181,16 @@ func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
if err != nil {
return nil, err
}
ret := &MemoryInfoStat{
RSS: uint64(k.KiRssize),
VMS: uint64(k.KiSize),
v, err := syscall.Sysctl("vm.stats.vm.v_page_size")
if err != nil {
return nil, err
}
pageSize := binary.LittleEndian.Uint16([]byte(v))
return ret, nil
return &MemoryInfoStat{
RSS: uint64(k.KiRssize) * uint64(pageSize),
VMS: uint64(k.KiSize),
}, nil
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return nil, common.NotImplementedError
@ -168,7 +200,19 @@ func (p *Process) MemoryPercent() (float32, error) {
}
func (p *Process) Children() ([]*Process, error) {
return nil, common.NotImplementedError
pids, err := common.CallPgrep(invoke, p.Pid)
if err != nil {
return nil, err
}
ret := make([]*Process, 0, len(pids))
for _, pid := range pids {
np, err := NewProcess(pid)
if err != nil {
return nil, err
}
ret = append(ret, np)
}
return ret, nil
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
@ -229,13 +273,9 @@ func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := binary.Read(br, binary.LittleEndian, &k)
if err != nil {
return k, err
}
return k, nil
}
func (p *Process) getKProc() (*KinfoProc, error) {
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}

View File

@ -10,8 +10,38 @@ const (
KernProcPID = 1 // by process id
KernProcProc = 8 // only return procs
KernProcPathname = 12 // path to executable
KernProcArgs = 7 // get/set arguments/proctitle
)
type Timespec struct {
Sec int32
Nsec int32
}
type Timeval struct {
Sec int32
Usec int32
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int32
Ixrss int32
Idrss int32
Isrss int32
Minflt int32
Majflt int32
Nswap int32
Inblock int32
Oublock int32
Msgsnd int32
Msgrcv int32
Nsignals int32
Nvcsw int32
Nivcsw int32
}
// copied from sys/user.h
type KinfoProc struct {
KiStructsize int32
@ -83,7 +113,7 @@ type KinfoProc struct {
KiNumthreads int32
KiTid int32
KiPri int32
KiRusage [72]byte
KiRusage Rusage
KiRusageCh [72]byte
KiPcb int32
KiKstack int32

View File

@ -1,6 +1,5 @@
// +build freebsd
// +build amd64
package process
// copied from sys/sysctl.h
@ -10,8 +9,38 @@ const (
KernProcPID = 1 // by process id
KernProcProc = 8 // only return procs
KernProcPathname = 12 // path to executable
KernProcArgs = 7 // get/set arguments/proctitle
)
type Timespec struct {
Sec int64
Nsec int64
}
type Timeval struct {
Sec int64
Usec int64
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int64
Ixrss int64
Idrss int64
Isrss int64
Minflt int64
Majflt int64
Nswap int64
Inblock int64
Oublock int64
Msgsnd int64
Msgrcv int64
Nsignals int64
Nvcsw int64
Nivcsw int64
}
// copied from sys/user.h
type KinfoProc struct {
KiStructsize int32
@ -83,7 +112,7 @@ type KinfoProc struct {
KiNumthreads int32
KiTid int32
KiPri int32
KiRusage [144]byte
KiRusage Rusage
KiRusageCh [144]byte
KiPcb int64
KiKstack int64

View File

@ -12,9 +12,9 @@ import (
"strings"
"syscall"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/host"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/net"
)
@ -203,11 +203,32 @@ func (p *Process) MemoryPercent() (float32, error) {
}
func (p *Process) Children() ([]*Process, error) {
return nil, common.NotImplementedError
pids, err := common.CallPgrep(invoke, p.Pid)
if err != nil {
return nil, err
}
ret := make([]*Process, 0, len(pids))
for _, pid := range pids {
np, err := NewProcess(pid)
if err != nil {
return nil, err
}
ret = append(ret, np)
}
return ret, nil
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return nil, common.NotImplementedError
_, ofs, err := p.fillFromfd()
if err != nil {
return nil, err
}
ret := make([]OpenFilesStat, 0, len(ofs))
for i, o := range ofs {
ret[i] = *o
}
return ret, nil
}
func (p *Process) Connections() ([]net.NetConnectionStat, error) {
@ -222,7 +243,7 @@ func (p *Process) IsRunning() (bool, error) {
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
pid := p.Pid
var ret []MemoryMapsStat
smapsPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "smaps")
smapsPath := common.HostProc(strconv.Itoa(int(pid)), "smaps")
contents, err := ioutil.ReadFile(smapsPath)
if err != nil {
return nil, err
@ -303,7 +324,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(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "fd")
statPath := common.HostProc(strconv.Itoa(int(pid)), "fd")
d, err := os.Open(statPath)
if err != nil {
return 0, nil, err
@ -336,7 +357,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(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "cwd")
cwdPath := common.HostProc(strconv.Itoa(int(pid)), "cwd")
cwd, err := os.Readlink(cwdPath)
if err != nil {
return "", err
@ -347,7 +368,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(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "exe")
exePath := common.HostProc(strconv.Itoa(int(pid)), "exe")
exe, err := os.Readlink(exePath)
if err != nil {
return "", err
@ -358,7 +379,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(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "cmdline")
cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
cmdline, err := ioutil.ReadFile(cmdPath)
if err != nil {
return "", err
@ -376,7 +397,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(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "io")
ioPath := common.HostProc(strconv.Itoa(int(pid)), "io")
ioline, err := ioutil.ReadFile(ioPath)
if err != nil {
return nil, err
@ -415,7 +436,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(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "statm")
memPath := common.HostProc(strconv.Itoa(int(pid)), "statm")
contents, err := ioutil.ReadFile(memPath)
if err != nil {
return nil, nil, err
@ -467,7 +488,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(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "status")
statPath := common.HostProc(strconv.Itoa(int(pid)), "status")
contents, err := ioutil.ReadFile(statPath)
if err != nil {
return err
@ -554,7 +575,7 @@ func (p *Process) fillFromStatus() error {
func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32, error) {
pid := p.Pid
statPath := filepath.Join(common.GetEnv("HOST_PROC", "/proc"), strconv.Itoa(int(pid)), "stat")
statPath := common.HostProc(strconv.Itoa(int(pid)), "stat")
contents, err := ioutil.ReadFile(statPath)
if err != nil {
return "", 0, nil, 0, 0, err
@ -610,7 +631,7 @@ func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32
func Pids() ([]int32, error) {
var ret []int32
d, err := os.Open(common.GetEnv("HOST_PROC", "/proc"))
d, err := os.Open(common.HostProc())
if err != nil {
return nil, err
}

View File

@ -8,7 +8,7 @@ import (
"testing"
"time"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
)
var mu sync.Mutex
@ -312,3 +312,19 @@ func Test_Connections(t *testing.T) {
t.Fatalf("wrong connections")
}
}
func Test_Children(t *testing.T) {
p, err := NewProcess(1)
if err != nil {
t.Fatalf("new process error %v", err)
}
c, err := p.Children()
if err != nil {
t.Fatalf("error %v", err)
}
if len(c) == 0 {
t.Fatalf("children is empty")
}
}

View File

@ -12,7 +12,7 @@ import (
"github.com/StackExchange/wmi"
"github.com/shirou/w32"
common "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/internal/common"
cpu "github.com/shirou/gopsutil/cpu"
net "github.com/shirou/gopsutil/net"
)

View File

@ -7,32 +7,37 @@ PATH := $(subst :,/bin:,$(GOPATH))/bin:$(PATH)
endif
# Standard Telegraf build
build: prepare
godep go build -o telegraf -ldflags \
default: prepare build
# Only run the build (no dependency grabbing)
build:
go build -o telegraf -ldflags \
"-X main.Version=$(VERSION)" \
./cmd/telegraf/telegraf.go
# Build with race detector
dev: prepare
godep go build -race -o telegraf -ldflags \
go build -race -o telegraf -ldflags \
"-X main.Version=$(VERSION)" \
./cmd/telegraf/telegraf.go
# Build linux 64-bit, 32-bit and arm architectures
build-linux-bins: prepare
GOARCH=amd64 GOOS=linux godep go build -o telegraf_linux_amd64 \
GOARCH=amd64 GOOS=linux go build -o telegraf_linux_amd64 \
-ldflags "-X main.Version=$(VERSION)" \
./cmd/telegraf/telegraf.go
GOARCH=386 GOOS=linux godep go build -o telegraf_linux_386 \
GOARCH=386 GOOS=linux go build -o telegraf_linux_386 \
-ldflags "-X main.Version=$(VERSION)" \
./cmd/telegraf/telegraf.go
GOARCH=arm GOOS=linux godep go build -o telegraf_linux_arm \
GOARCH=arm GOOS=linux go build -o telegraf_linux_arm \
-ldflags "-X main.Version=$(VERSION)" \
./cmd/telegraf/telegraf.go
# Get godep
# Get dependencies and use godep to checkout changesets
prepare:
go get ./...
go get github.com/tools/godep
godep restore
# Run all docker containers necessary for unit tests
docker-run:
@ -84,10 +89,10 @@ test: docker-kill prepare docker-run
# Sleeping for kafka leadership election, TSDB setup, etc.
sleep 60
# SUCCESS, running tests
godep go test -race ./...
go test -race ./...
# Run "short" unit tests
test-short: prepare
godep go test -short ./...
go test -short ./...
.PHONY: test

View File

@ -10,6 +10,8 @@ machine:
- go version
dependencies:
cache_directories:
- "~/telegraf-build/src"
override:
- docker info

View File

@ -35,11 +35,11 @@ func NewConfig() *Config {
c := &Config{
// Agent defaults:
Agent: &AgentConfig{
Interval: internal.Duration{10 * time.Second},
Interval: internal.Duration{Duration: 10 * time.Second},
RoundInterval: true,
FlushInterval: internal.Duration{10 * time.Second},
FlushInterval: internal.Duration{Duration: 10 * time.Second},
FlushRetries: 2,
FlushJitter: internal.Duration{5 * time.Second},
FlushJitter: internal.Duration{Duration: 5 * time.Second},
},
Tags: make(map[string]string),

View File

@ -10,7 +10,7 @@ import (
// Duration just wraps time.Duration
type Duration struct {
time.Duration
Duration time.Duration
}
// UnmarshalTOML parses the duration from the TOML config file

View File

@ -57,7 +57,7 @@ exit_if_fail make
exit_if_fail godep go vet ./...
exit_if_fail make docker-run-circle
sleep 10
exit_if_fail godep go test -race ./...
exit_if_fail go test -race ./...
# Simple Integration Tests
# check that version was properly set

View File

@ -134,7 +134,8 @@ do_build() {
rm -f $GOPATH_INSTALL/bin/$b
done
godep go install -ldflags="-X main.Version $version" ./...
godep restore
go install -ldflags="-X main.Version $version" ./...
if [ $? -ne 0 ]; then
echo "Build failed, unable to create package -- aborting"
cleanup_exit 1