github.com/distbuild/reclient@v0.0.0-20240401075343-3de72e395564/internal/pkg/localresources/usage/usage.go (about) 1 package usage 2 3 import ( 4 "os" 5 "time" 6 7 log "github.com/golang/glog" 8 "github.com/shirou/gopsutil/v3/process" 9 ) 10 11 // These are the names of the proxy's resource usage stats. 12 const ( 13 CPUPct = "CPU_pct" 14 MemPct = "MEM_pct" 15 // MemVirt is the total amount of virtual memory used by the current process, 16 // includes physically memory used by code, data and libraries, also pages 17 // have been swapped out and pages have been mapped but not used yet. 18 MemVirt = "MEM_VIRT_mbs" 19 // MemRes is a subset of MemVirt, includes the non-swapping physical memory 20 // the process is actively using only. 21 MemRes = "MEM_RES_mbs" 22 mb uint64 = 1024 * 1024 23 ) 24 25 // PsutilSampler is an instance that reports the usage of OS resource. 26 type PsutilSampler struct { 27 Sampler 28 } 29 30 // Sampler is an interface that can provide the sampled system resource usage. 31 type Sampler interface { 32 Percent(interval time.Duration) (float64, error) 33 MemoryPercent() (float32, error) 34 MemoryInfo() (*process.MemoryInfoStat, error) 35 } 36 37 // New a PsutilSampler instance with current process's pid. 38 func New() *PsutilSampler { 39 p, err := process.NewProcess(int32(os.Getpid())) 40 if err != nil { 41 log.Errorf("Cannot create a NewProcess instance to monitor proxy resource usage.") 42 return nil 43 } 44 return &PsutilSampler{p} 45 } 46 47 // Sample returns the current resource usage data by performing a new measurement. 48 func Sample(uSampler Sampler) map[string]int64 { 49 if uSampler == nil { 50 return nil 51 } 52 // resource usage by current proxy's process 53 cPercent, err := uSampler.Percent(0) 54 if err != nil { 55 log.Errorf("Failed to get current process's CPU percent: %v", err) 56 return nil 57 } 58 mPercent, err := uSampler.MemoryPercent() 59 if err != nil { 60 log.Errorf("Failed to get current process's Mem percent: %v", err) 61 return nil 62 } 63 mInfo, err := uSampler.MemoryInfo() 64 if err != nil { 65 log.Errorf("Failed to get current process's Mem info: %v", err) 66 return nil 67 } 68 res := map[string]int64{} 69 res[CPUPct] = int64(cPercent) 70 res[MemPct] = int64(mPercent) 71 res[MemVirt] = int64(mInfo.VMS / mb) 72 res[MemRes] = int64(mInfo.RSS / mb) 73 return res 74 }