diff --git a/resources/psutil/process.go b/resources/psutil/process.go index 033e8756..13ebccbf 100644 --- a/resources/psutil/process.go +++ b/resources/psutil/process.go @@ -95,7 +95,7 @@ func (p *process) tickCPU(ctx context.Context, interval time.Duration) { } func (p *process) collectCPU() cpuTimesStat { - stat, err := p.cpuTimes() + stat, err := cpuTimes(p.pid) if err != nil { return cpuTimesStat{ total: float64(time.Now().Unix()), @@ -103,9 +103,49 @@ func (p *process) collectCPU() cpuTimesStat { } } + cstat := p.collectCPUFromChildren(p.proc) + + stat.total += cstat.total + stat.system += cstat.system + stat.user += cstat.user + stat.idle += cstat.idle + stat.other += cstat.other + return *stat } +func (p *process) collectCPUFromChildren(proc *psprocess.Process) *cpuTimesStat { + stat := cpuTimesStat{} + + children, err := proc.Children() + if err != nil { + return &stat + } + + for _, child := range children { + cstat, err := cpuTimes(child.Pid) + if err != nil { + continue + } + + stat.total += cstat.total + stat.system += cstat.system + stat.user += cstat.user + stat.idle += cstat.idle + stat.other += cstat.other + + cstat = p.collectCPUFromChildren(child) + + stat.total += cstat.total + stat.system += cstat.system + stat.user += cstat.user + stat.idle += cstat.idle + stat.other += cstat.other + } + + return &stat +} + func (p *process) tickMemory(ctx context.Context, interval time.Duration) { ticker := time.NewTicker(interval) defer ticker.Stop() @@ -130,7 +170,33 @@ func (p *process) collectMemory() uint64 { return 0 } - return info.RSS + rss := info.RSS + + rss += p.collectMemoryFromChildren(p.proc) + + return rss +} + +func (p *process) collectMemoryFromChildren(proc *psprocess.Process) uint64 { + children, err := proc.Children() + if err != nil { + return 0 + } + + rss := uint64(0) + + for _, child := range children { + info, err := child.MemoryInfo() + if err != nil { + continue + } + + rss += info.RSS + + rss += p.collectMemoryFromChildren(child) + } + + return rss } func (p *process) Cancel() { diff --git a/resources/psutil/process_linux.go b/resources/psutil/process_linux.go index e5b8894a..dd8cb135 100644 --- a/resources/psutil/process_linux.go +++ b/resources/psutil/process_linux.go @@ -27,13 +27,13 @@ func init() { } } -func (p *process) cpuTimes() (*cpuTimesStat, error) { +func cpuTimes(pid int32) (*cpuTimesStat, error) { value := os.Getenv("HOST_PROC") if value == "" { value = "/proc" } - path := filepath.Join(value, strconv.FormatInt(int64(p.pid), 10), "stat") + path := filepath.Join(value, strconv.FormatInt(int64(pid), 10), "stat") contents, err := os.ReadFile(path) if err != nil { diff --git a/resources/psutil/process_other.go b/resources/psutil/process_other.go index f5464906..bfcf2aea 100644 --- a/resources/psutil/process_other.go +++ b/resources/psutil/process_other.go @@ -3,8 +3,15 @@ package psutil -func (p *process) cpuTimes() (*cpuTimesStat, error) { - times, err := p.proc.Times() +import psprocess "github.com/shirou/gopsutil/v3/process" + +func cpuTimes(pid int32) (*cpuTimesStat, error) { + proc, err := psprocess.NewProcess(pid) + if err != nil { + return nil, err + } + + times, err := proc.Times() if err != nil { return nil, err }