diff --git a/disk/disk_linux.go b/disk/disk_linux.go index 0bc6e2f..f5eb526 100644 --- a/disk/disk_linux.go +++ b/disk/disk_linux.go @@ -6,6 +6,7 @@ import ( "context" "fmt" "os/exec" + "path/filepath" "strconv" "strings" @@ -289,6 +290,11 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC ret := make(map[string]IOCountersStat, 0) empty := IOCountersStat{} + // use only basename such as "/dev/sda1" to "sda1" + for i, name := range names { + names[i] = filepath.Base(name) + } + for _, line := range lines { fields := strings.Fields(line) if len(fields) < 14 { diff --git a/disk/disk_test.go b/disk/disk_test.go index 436b8a5..269ca6c 100644 --- a/disk/disk_test.go +++ b/disk/disk_test.go @@ -25,6 +25,8 @@ func TestDisk_partitions(t *testing.T) { if err != nil || len(ret) == 0 { t.Errorf("error %v", err) } + t.Log(ret) + empty := PartitionStat{} if len(ret) == 0 { t.Errorf("ret is empty") @@ -46,6 +48,7 @@ func TestDisk_io_counters(t *testing.T) { } empty := IOCountersStat{} for part, io := range ret { + t.Log(part, io) if io == empty { t.Errorf("io_counter error %v, %v", part, io) } diff --git a/docker/docker.go b/docker/docker.go index 1d932cf..83716fd 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -1,6 +1,7 @@ package docker import ( + "encoding/json" "errors" "github.com/shirou/gopsutil/internal/common" @@ -50,6 +51,11 @@ type CgroupMemStat struct { MemFailCnt uint64 `json:"memoryFailcnt"` } +func (m CgroupMemStat) String() string { + s, _ := json.Marshal(m) + return string(s) +} + type CgroupDockerStat struct { ContainerID string `json:"containerID"` Name string `json:"name"` @@ -57,3 +63,8 @@ type CgroupDockerStat struct { Status string `json:"status"` Running bool `json:"running"` } + +func (c CgroupDockerStat) String() string { + s, _ := json.Marshal(c) + return string(s) +} diff --git a/docker/docker_linux.go b/docker/docker_linux.go index 8c722a0..c0724db 100644 --- a/docker/docker_linux.go +++ b/docker/docker_linux.go @@ -57,11 +57,6 @@ func GetDockerStatWithContext(ctx context.Context) ([]CgroupDockerStat, error) { return ret, nil } -func (c CgroupDockerStat) String() string { - s, _ := json.Marshal(c) - return string(s) -} - // GetDockerIDList returnes a list of DockerID. // This requires certain permission. func GetDockerIDList() ([]string, error) { @@ -245,11 +240,6 @@ func CgroupMemDockerWithContext(ctx context.Context, containerID string) (*Cgrou 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 { diff --git a/host/host_linux.go b/host/host_linux.go index 65f3b64..e0b4b60 100644 --- a/host/host_linux.go +++ b/host/host_linux.go @@ -104,7 +104,18 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { if t != 0 { return t, nil } - filename := common.HostProc("stat") + + system, role, err := Virtualization() + if err != nil { + return 0, err + } + statFile := "stat" + if system == "lxc" && role == "guest" { + // if lxc, /proc/uptime is used. + statFile = "uptime" + } + + filename := common.HostProc(statFile) lines, err := common.ReadLines(filename) if err != nil { return 0, err diff --git a/host/host_test.go b/host/host_test.go index c420580..87a6bd9 100644 --- a/host/host_test.go +++ b/host/host_test.go @@ -40,11 +40,13 @@ func TestBoot_time(t *testing.T) { if v < 946652400 { t.Errorf("Invalid Boottime, older than 2000-01-01") } + t.Logf("first boot time: %d", v) v2, err := BootTime() if v != v2 { t.Errorf("cached boot time is different") } + t.Logf("second boot time: %d", v2) } func TestUsers(t *testing.T) { diff --git a/process/process.go b/process/process.go index 09b1e6a..e20742a 100644 --- a/process/process.go +++ b/process/process.go @@ -31,6 +31,8 @@ type Process struct { lastCPUTimes *cpu.TimesStat lastCPUTime time.Time + + tgid int32 } type OpenFilesStat struct { diff --git a/process/process_darwin.go b/process/process_darwin.go index 005ae3c..97d1c49 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -96,6 +96,9 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return common.IntToString(k.Proc.P_comm[:]), nil } +func (p *Process) Tgid() (int32, error) { + return 0, common.ErrNotImplementedError +} func (p *Process) Exe() (string, error) { return p.ExeWithContext(context.Background()) } diff --git a/process/process_fallback.go b/process/process_fallback.go index bc3bb1d..2f18afe 100644 --- a/process/process_fallback.go +++ b/process/process_fallback.go @@ -54,6 +54,9 @@ func (p *Process) Name() (string, error) { func (p *Process) NameWithContext(ctx context.Context) (string, error) { return "", common.ErrNotImplementedError } +func (p *Process) Tgid() (int32, error) { + return 0, common.ErrNotImplementedError +} func (p *Process) Exe() (string, error) { return p.ExeWithContext(context.Background()) } diff --git a/process/process_freebsd.go b/process/process_freebsd.go index 7b85e8a..29a223a 100644 --- a/process/process_freebsd.go +++ b/process/process_freebsd.go @@ -63,6 +63,9 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return common.IntToString(k.Comm[:]), nil } +func (p *Process) Tgid() (int32, error) { + return 0, common.ErrNotImplementedError +} func (p *Process) Exe() (string, error) { return p.ExeWithContext(context.Background()) } diff --git a/process/process_linux.go b/process/process_linux.go index a9aed88..14d151b 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -109,6 +109,16 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return p.name, nil } +// Tgid returns tgid, a Linux-synonym for user-space Pid +func (p *Process) Tgid() (int32, error) { + if p.tgid == 0 { + if err := p.fillFromStatus(); err != nil { + return 0, err + } + } + return p.tgid, nil +} + // Exe returns executable path of the process. func (p *Process) Exe() (string, error) { return p.ExeWithContext(context.Background()) @@ -985,6 +995,12 @@ func (p *Process) fillFromStatusWithContext(ctx context.Context) error { return err } p.parent = int32(pval) + case "Tgid": + pval, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return err + } + p.tgid = int32(pval) case "Uid": p.uids = make([]int32, 0, 4) for _, i := range strings.Split(value, "\t") { diff --git a/process/process_openbsd.go b/process/process_openbsd.go index 2a8eec7..857bad0 100644 --- a/process/process_openbsd.go +++ b/process/process_openbsd.go @@ -66,6 +66,9 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return common.IntToString(k.Comm[:]), nil } +func (p *Process) Tgid() (int32, error) { + return 0, common.ErrNotImplementedError +} func (p *Process) Exe() (string, error) { return p.ExeWithContext(context.Background()) } diff --git a/process/process_windows.go b/process/process_windows.go index c875ec2..f1fa1cb 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -170,6 +170,10 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return name, nil } +func (p *Process) Tgid() (int32, error) { + return 0, common.ErrNotImplementedError +} + func (p *Process) Exe() (string, error) { return p.ExeWithContext(context.Background()) }