From e6517d4140351578234145926923d19a3eb6a7e7 Mon Sep 17 00:00:00 2001 From: Cameron Sparr Date: Fri, 4 Dec 2015 11:44:56 -0700 Subject: [PATCH] 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. --- Godeps/Godeps.json | 37 +++--- .../shirou/gopsutil/cpu/cpu_darwin_nocgo.go | 2 +- .../shirou/gopsutil/cpu/cpu_freebsd.go | 2 +- .../shirou/gopsutil/cpu/cpu_linux.go | 71 +++++++++--- .../shirou/gopsutil/cpu/cpu_test.go | 3 +- .../shirou/gopsutil/cpu/cpu_windows.go | 2 +- .../shirou/gopsutil/disk/disk_darwin.go | 2 +- .../shirou/gopsutil/disk/disk_freebsd.go | 2 +- .../shirou/gopsutil/disk/disk_freebsd_386.go | 108 ++++++++++++++++++ .../shirou/gopsutil/disk/disk_linux.go | 4 +- .../shirou/gopsutil/disk/disk_unix.go | 2 +- .../shirou/gopsutil/disk/disk_windows.go | 2 +- .../shirou/gopsutil/docker/docker.go | 4 + .../shirou/gopsutil/docker/docker_linux.go | 101 ++++++++++------ .../gopsutil/docker/docker_linux_test.go | 4 +- .../shirou/gopsutil/docker/docker_notlinux.go | 5 +- .../github.com/shirou/gopsutil/host/host.go | 1 + .../shirou/gopsutil/host/host_darwin.go | 26 +++-- .../shirou/gopsutil/host/host_freebsd.go | 29 +++-- .../shirou/gopsutil/host/host_linux.go | 30 +++-- .../shirou/gopsutil/host/host_linux_386.go | 50 ++++---- .../shirou/gopsutil/host/host_test.go | 3 +- .../shirou/gopsutil/host/host_windows.go | 23 +++- .../shirou/gopsutil/load/load_darwin.go | 2 +- .../shirou/gopsutil/load/load_freebsd.go | 2 +- .../shirou/gopsutil/load/load_linux.go | 4 +- .../shirou/gopsutil/load/load_windows.go | 2 +- .../shirou/gopsutil/mem/mem_darwin.go | 2 +- .../shirou/gopsutil/mem/mem_freebsd.go | 11 +- .../shirou/gopsutil/mem/mem_linux.go | 6 +- .../shirou/gopsutil/mem/mem_windows.go | 2 +- .../src/github.com/shirou/gopsutil/net/net.go | 13 ++- .../shirou/gopsutil/net/net_darwin.go | 11 +- .../shirou/gopsutil/net/net_freebsd.go | 11 +- .../shirou/gopsutil/net/net_linux.go | 75 +++++++++++- .../shirou/gopsutil/net/net_test.go | 55 +++++++++ .../shirou/gopsutil/net/net_unix.go | 2 +- .../shirou/gopsutil/net/net_windows.go | 11 +- .../shirou/gopsutil/process/process.go | 2 +- .../shirou/gopsutil/process/process_darwin.go | 16 ++- .../gopsutil/process/process_freebsd.go | 70 +++++++++--- .../gopsutil/process/process_freebsd_386.go | 32 +++++- .../gopsutil/process/process_freebsd_amd64.go | 33 +++++- .../shirou/gopsutil/process/process_linux.go | 47 +++++--- .../shirou/gopsutil/process/process_test.go | 18 ++- .../gopsutil/process/process_windows.go | 2 +- Makefile | 23 ++-- circle.yml | 2 + internal/config/config.go | 6 +- internal/internal.go | 2 +- scripts/circle-test.sh | 2 +- scripts/package.sh | 3 +- 52 files changed, 762 insertions(+), 218 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd_386.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index c49bdcd5c..677858f3a 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -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", diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go index ca545705c..0b7d1f999 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_freebsd.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_freebsd.go index 2c22a3953..5df67b3d4 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_freebsd.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_freebsd.go @@ -9,7 +9,7 @@ import ( "strconv" "strings" - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) // sys/resource.h diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_linux.go index 1bec8a73f..8dbbd8536 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_linux.go @@ -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,16 +147,19 @@ func CPUInfo() ([]CPUInfoStat, error) { c.PhysicalID = value case "core id": c.CoreID = value - case "cpu cores": - t, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return ret, err - } - c.Cores = int32(t) - case "flags": - c.Flags = strings.Split(value, ",") + 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 + } + ret = append(ret, c) + } return ret, nil } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_test.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_test.go index 7de17a767..9695e35f4 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_test.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_test.go @@ -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) } } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_windows.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_windows.go index 96f4c70f6..408d6a686 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_windows.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/cpu/cpu_windows.go @@ -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 { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin.go index 095bbda63..fbf97c610 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin.go @@ -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) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd.go index 11dd495d4..7e32c4b63 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd.go @@ -9,7 +9,7 @@ import ( "syscall" "unsafe" - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) const ( diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd_386.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd_386.go new file mode 100644 index 000000000..7b6eff1be --- /dev/null +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd_386.go @@ -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 +} diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_linux.go index 93f59b098..caa1e17f7 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_linux.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_unix.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_unix.go index f006c1ac5..e081b9d47 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_unix.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_unix.go @@ -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)), } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_windows.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_windows.go index 24f8b170e..5ebe2dbcb 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_windows.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_windows.go @@ -9,7 +9,7 @@ import ( "github.com/StackExchange/wmi" - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) var ( diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker.go index 83a92be24..eda941d3f 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker.go @@ -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"` } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux.go index fd6df6d8b..1b6ac9a75 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux.go @@ -4,14 +4,15 @@ package docker import ( "encoding/json" - "os" + "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-.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-.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) +} diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux_test.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux_test.go index 48cedfba7..c284d5a69 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux_test.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_linux_test.go @@ -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. diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_notlinux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_notlinux.go index fb59e21cc..b45f96c80 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_notlinux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/docker/docker_notlinux.go @@ -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 { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host.go index 523b63461..241ceb23e 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin.go index 0a0e462c0..069c6fa37 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd.go index edff5b7ec..4a151fd84 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd.go @@ -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) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux.go index 9131fa84d..91b153074 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux.go @@ -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" diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_386.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_386.go index d8f31c2f6..fb6d7a0f6 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_386.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_386.go @@ -6,39 +6,39 @@ package host const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 + sizeofPtr = 0x4 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x4 + sizeofLongLong = 0x8 ) type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 + _C_short int16 + _C_int int32 + _C_long int32 + _C_long_long int64 ) type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv UtTv - Addr_v6 [4]int32 - X__unused [20]int8 + Type int16 + Pad_cgo_0 [2]byte + Pid int32 + Line [32]int8 + Id [4]int8 + User [32]int8 + Host [256]int8 + Exit exit_status + Session int32 + Tv UtTv + Addr_v6 [4]int32 + X__unused [20]int8 } type exit_status struct { - Termination int16 - Exit int16 + Termination int16 + Exit int16 } type UtTv struct { - TvSec int32 - TvUsec int32 + TvSec int32 + TvUsec int32 } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_test.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_test.go index eb6982904..abcb0b6a3 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_test.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_test.go @@ -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) } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_windows.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_windows.go index e8ba125d9..13890bf2b 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_windows.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_windows.go @@ -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() diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_darwin.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_darwin.go index d90a42902..0d1c7ecc0 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_darwin.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_darwin.go @@ -5,7 +5,7 @@ package load import ( "strconv" - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) func LoadAvg() (*LoadAvgStat, error) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_freebsd.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_freebsd.go index d82afbecc..e97c5698b 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_freebsd.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_freebsd.go @@ -5,7 +5,7 @@ package load import ( "strconv" - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) func LoadAvg() (*LoadAvgStat, error) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_linux.go index 4ab5a9686..80621c966 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_linux.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_windows.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_windows.go index 70ad565d8..65a6ba730 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_windows.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/load/load_windows.go @@ -3,7 +3,7 @@ package load import ( - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) func LoadAvg() (*LoadAvgStat, error) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin.go index 921d87096..ba4dbd826 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) func getPageSize() (uint64, error) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_freebsd.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_freebsd.go index 2791fca82..0cb33abc4 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_freebsd.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_freebsd.go @@ -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") } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_linux.go index e45a0842d..fc9226219 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_linux.go @@ -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) diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_windows.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_windows.go index 985ab8fdf..2696da58e 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_windows.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_windows.go @@ -6,7 +6,7 @@ import ( "syscall" "unsafe" - common "github.com/shirou/gopsutil/common" + "github.com/shirou/gopsutil/internal/common" ) var ( diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net.go index 506fe57e0..61f9abf04 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net.go @@ -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) diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_darwin.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_darwin.go index 65c21f882..7786f7c41 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_darwin.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_darwin.go @@ -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") +} diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_freebsd.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_freebsd.go index 703d3219d..6dc7a23d5 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_freebsd.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_freebsd.go @@ -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") +} diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_linux.go index 73b2bee6c..51d80913c 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_linux.go @@ -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 +} diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_test.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_test.go index 9337e53f9..187c320d1 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_test.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_test.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_unix.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_unix.go index 0b8a844e7..fe2f1eb4d 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_unix.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_unix.go @@ -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. diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_windows.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_windows.go index 8937c4e89..33aceb657 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_windows.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/net/net_windows.go @@ -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") +} diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process.go index abe522c80..0526f78a7 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin.go index dab9f1366..a8fce7d2e 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin.go @@ -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) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd.go index 5fce20838..ecd89204c 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd.go @@ -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,11 +273,7 @@ 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 + return k, err } func (p *Process) getKProc() (*KinfoProc, error) { diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_386.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_386.go index 4d9ebfdb3..6b3bdfc72 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_386.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_386.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go index 0dafda2d2..69a352f34 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go @@ -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 diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux.go index 0d3a3973e..116de00f9 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux.go @@ -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 } diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_test.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_test.go index 854d63c12..153302e7f 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_test.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_test.go @@ -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") + } + +} diff --git a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_windows.go b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_windows.go index 124ea7568..d7a4b1cb6 100644 --- a/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_windows.go +++ b/Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_windows.go @@ -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" ) diff --git a/Makefile b/Makefile index ec7e7c169..758e8e59a 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/circle.yml b/circle.yml index 9c5a87b05..c1c2d35ab 100644 --- a/circle.yml +++ b/circle.yml @@ -10,6 +10,8 @@ machine: - go version dependencies: + cache_directories: + - "~/telegraf-build/src" override: - docker info diff --git a/internal/config/config.go b/internal/config/config.go index 5bb77f2c6..f16803142 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -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), diff --git a/internal/internal.go b/internal/internal.go index e681aafcd..eb690fdc4 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -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 diff --git a/scripts/circle-test.sh b/scripts/circle-test.sh index e3b66e8f2..6a51d4fbb 100755 --- a/scripts/circle-test.sh +++ b/scripts/circle-test.sh @@ -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 diff --git a/scripts/package.sh b/scripts/package.sh index 8f0efbacc..7a786e9f4 100755 --- a/scripts/package.sh +++ b/scripts/package.sh @@ -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