diff --git a/cmd/perfmon.go b/cmd/perfmon.go index 89cde12..70ff252 100644 --- a/cmd/perfmon.go +++ b/cmd/perfmon.go @@ -18,8 +18,15 @@ package cmd import ( - "github.com/SonicCloudOrg/sonic-android-supply/cmd/perfmon" + "fmt" + "github.com/SonicCloudOrg/sonic-android-supply/src/entity" + "github.com/SonicCloudOrg/sonic-android-supply/src/perfmonUtil" + "github.com/SonicCloudOrg/sonic-android-supply/src/util" "github.com/spf13/cobra" + "log" + "os" + "os/signal" + "time" ) var perfmonCmd = &cobra.Command{ @@ -27,11 +34,75 @@ var perfmonCmd = &cobra.Command{ Short: "Get device performance", Long: "Get device performance", Run: func(cmd *cobra.Command, args []string) { - cmd.Help() + device := util.GetDevice(serial) + pid, err := perfmonUtil.GetPidOnPackageName(device, packageName) + if err != nil { + fmt.Println("no corresponding application PID found") + pid = "" + } + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, os.Kill) + + if !perfOptions.ProcMem && !perfOptions.ProcCPU && + !perfOptions.ProcFPS && !perfOptions.SystemCPU && + !perfOptions.SystemGPU && !perfOptions.SystemNetWorking && + !perfOptions.SystemMem{ + perfOptions.SystemCPU = true + perfOptions.SystemMem = true + } + + timer := time.Tick(time.Duration(refreshTime * int(time.Millisecond))) + done := false + for !done { + select { + case <-sig: + done = true + fmt.Println() + case <-timer: + sysStatus,err1 := perfmonUtil.GetSystemStats(device,perfOptions) + if err1 != nil { + log.Panic(err1) + } + processInfo, err2 := perfmonUtil.GetProcessInfo(device, pid, packageName,perfOptions, 1) + if err2 != nil { + log.Panic(err2) + } + var perfData = &entity.PerfmonData{} + perfData.System = sysStatus + perfData.Process = processInfo + perfData.TimeStamp = time.Now().Unix() + + data := util.ResultData(perfData) + fmt.Println(util.Format(data, isFormat, isJson)) + + } + } }, } +var ( + perfOptions entity.PerfOption + pid int + packageName string + refreshTime int +) + func init() { rootCmd.AddCommand(perfmonCmd) - perfmon.InitPerfmon(perfmonCmd) + perfmonCmd.Flags().StringVarP(&serial, "serial", "s", "", "device serial") + perfmonCmd.Flags().IntVarP(&pid, "pid", "d", -1, "get PID data") + perfmonCmd.Flags().StringVarP(&packageName, "", "p", "", "app package name") + perfmonCmd.Flags().BoolVar(&perfOptions.SystemCPU, "sys-cpu", false, "get system cpu data") + perfmonCmd.Flags().BoolVar(&perfOptions.SystemMem, "sys-mem", false, "get system memory data") + //perfmonCmd.Flags().BoolVar(&sysDisk, "sys-disk", false, "get system disk data") + perfmonCmd.Flags().BoolVar(&perfOptions.SystemNetWorking, "sys-network", false, "get system networking data") + perfmonCmd.Flags().BoolVar(&perfOptions.SystemGPU, "gpu", false, "get gpu data") + perfmonCmd.Flags().BoolVar(&perfOptions.ProcFPS, "proc-fps", false, "get fps data") + perfmonCmd.Flags().BoolVar(&perfOptions.ProcThreads,"proc-threads",false,"get process threads") + //perfmonCmd.Flags().BoolVar(&, "proc-network", false, "get process network data") + perfmonCmd.Flags().BoolVar(&perfOptions.ProcCPU, "proc-cpu", false, "get process cpu data") + perfmonCmd.Flags().BoolVar(&perfOptions.SystemMem, "proc-mem", false, "get process mem data") + perfmonCmd.Flags().IntVarP(&refreshTime, "refresh", "r", 1000, "data refresh time(millisecond)") + perfmonCmd.Flags().BoolVarP(&isFormat, "format", "f", false, "convert to JSON string and format") + perfmonCmd.Flags().BoolVarP(&isJson, "json", "j", false, "convert to JSON string") } diff --git a/cmd/perfmon/process.go b/cmd/perfmon/process.go deleted file mode 100644 index 78ae0f4..0000000 --- a/cmd/perfmon/process.go +++ /dev/null @@ -1,77 +0,0 @@ -/* - * sonic-android-supply Supply of ADB. - * Copyright (C) 2022 SonicCloudOrg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package perfmon - -import ( - "fmt" - "github.com/SonicCloudOrg/sonic-android-supply/src/perfmonUtil" - "github.com/SonicCloudOrg/sonic-android-supply/src/util" - "github.com/spf13/cobra" - "log" - "os" - "os/signal" - "time" -) - -var processPerfmonCmd = &cobra.Command{ - Use: "process", - Short: "Get app performance", - Long: "Get app performance", - RunE: func(cmd *cobra.Command, args []string) (err error) { - device := util.GetDevice(serial) - pid, err := perfmonUtil.GetPidOnPackageName(device, appName) - if err != nil { - return err - } - if pid == "" { - return fmt.Errorf("not find app corresponding pid") - } - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, os.Kill) - timer := time.Tick(time.Duration(interval * int(time.Millisecond))) - done := false - for !done { - select { - case <-sig: - done = true - fmt.Println() - case <-timer: - if processInfo, err := perfmonUtil.GetProcessInfo(device, pid, appName, 1); err != nil { - log.Panic(err) - } else { - processInfo.Name = appName - data := util.ResultData(processInfo) - fmt.Println(util.Format(data, isFormat, isJson)) - } - } - } - return nil - }, -} - -var appName string - -func initProcessPerfmon() { - perfmonRootCMD.AddCommand(processPerfmonCmd) - processPerfmonCmd.Flags().StringVarP(&appName, "name", "n", "", "application name") - processPerfmonCmd.MarkFlagRequired("name") - processPerfmonCmd.Flags().StringVarP(&serial, "serial", "s", "", "device serial") - processPerfmonCmd.Flags().IntVarP(&interval, "interval", "i", 1000, "data refresh time") - processPerfmonCmd.Flags().BoolVarP(&isJson, "json", "j", false, "convert to JSON string") - processPerfmonCmd.Flags().BoolVarP(&isFormat, "format", "f", false, "convert to JSON string and format") -} diff --git a/cmd/perfmon/system.go b/cmd/perfmon/system.go deleted file mode 100644 index ccbe43f..0000000 --- a/cmd/perfmon/system.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - * sonic-android-supply Supply of ADB. - * Copyright (C) 2022 SonicCloudOrg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package perfmon - -import ( - "fmt" - "github.com/SonicCloudOrg/sonic-android-supply/src/perfmonUtil" - "github.com/SonicCloudOrg/sonic-android-supply/src/util" - "github.com/spf13/cobra" - "os" - "os/signal" - "time" -) - -var systemPerfmonCmd = &cobra.Command{ - Use: "system", - Short: "Get system performance data", - Long: "Get system performance data", - Run: func(cmd *cobra.Command, args []string) { - device := util.GetDevice(serial) - perfmonUtil.GetSystemStats(device) - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, os.Kill) - - timer := time.Tick(time.Duration(interval * int(time.Millisecond))) - done := false - for !done { - select { - case <-sig: - done = true - return - case <-timer: - status := perfmonUtil.GetSystemStats(device) - data := util.ResultData(status) - fmt.Println(util.Format(data, isFormat, isJson)) - } - } - }, -} - -func initSystemPerfmon() { - perfmonRootCMD.AddCommand(systemPerfmonCmd) - systemPerfmonCmd.Flags().StringVarP(&serial, "serial", "s", "", "device serial") - systemPerfmonCmd.Flags().IntVarP(&interval, "interval", "i", 1000, "data refresh time") - systemPerfmonCmd.Flags().BoolVarP(&isJson, "json", "j", false, "convert to JSON string") - systemPerfmonCmd.Flags().BoolVarP(&isFormat, "format", "f", false, "convert to JSON string and format") -} diff --git a/cmd/root.go b/cmd/root.go index b41c3e5..82ead4a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -39,7 +39,11 @@ https://github.com/SonicCloudOrg/sonic-android-supply `, } -var serial string +var ( + serial string + isFormat bool + isJson bool +) // Execute error func Execute() { diff --git a/cmd/perfmon/perfmonInit.go b/src/entity/perfmon.go similarity index 62% rename from cmd/perfmon/perfmonInit.go rename to src/entity/perfmon.go index 021176d..1afb47a 100644 --- a/cmd/perfmon/perfmonInit.go +++ b/src/entity/perfmon.go @@ -15,23 +15,24 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package perfmon +package entity -import ( - "github.com/spf13/cobra" -) +import "encoding/json" -var perfmonRootCMD *cobra.Command - -var ( - interval int - isJson bool - isFormat bool - serial string -) +type PerfmonData struct { + System *SystemInfo `json:"system,omitempty"` + Process *ProcessInfo `json:"process,omitempty"` + TimeStamp int64 `json:"timeStamp"` +} -func InitPerfmon(perfmonCMD *cobra.Command) { - perfmonRootCMD = perfmonCMD - initProcessPerfmon() - initSystemPerfmon() +func (p *PerfmonData) ToJson() string { + str, _ := json.Marshal(p) + return string(str) +} +func (p *PerfmonData) ToString() string { + return p.ToJson() +} +func (p *PerfmonData) ToFormat() string { + str, _ := json.MarshalIndent(p, "", "\t") + return string(str) } diff --git a/src/entity/process.go b/src/entity/process.go index 37dca41..0e248ff 100644 --- a/src/entity/process.go +++ b/src/entity/process.go @@ -19,7 +19,6 @@ package entity import ( "encoding/json" - "fmt" ) type ProcessIO struct { @@ -109,16 +108,11 @@ type ProcessStatus struct { type ProcessInfo struct { Name string `json:"name"` Pid string `json:"pid"` - CpuUtilization float64 `json:"cpuUtilization"` - //ReadBytes int `json:"readBytes"` - //WriteBytes int `json:"writeBytes"` - PhyRSS int `json:"phyRSS"` - VmSize int `json:"vmRSS"` - Threads int `json:"threadCount"` - Rchar int `json:"readCharCount"` - Wchar int `json:"writeCharCount"` - FPS int `json:"fps"` - TimeStamp int64 `json:"timeStamp"` + CpuUtilization *float64 `json:"cpuUtilization"` + PhyRSS *int `json:"phyRSS"` + VmSize *int `json:"vmRSS"` + Threads *int `json:"threadCount"` + FPS *int `json:"fps"` } func (i *ProcessInfo) ToJson() string { @@ -131,35 +125,33 @@ func (i *ProcessInfo) ToFormat() string { return string(str) } -func (i *ProcessInfo) ToString() string { - - var result = fmt.Sprintf( - //%s%s%s%s up %s%s%s - ` -PID:%s%s%s Name:%s%s%s - -CPU: - %s%.2f%s%% cpuUtilizetion - %s%d%s ThreadCount - -Memory: - physicalMemory = %s%d%s - virtualMemory = %s%d%s - -R/W char: - Rchar = %s%d%s - Wchar = %s%d%s - -`, - escBrightWhite, i.Name, escReset, - escBrightWhite, i.Pid, escReset, - escBrightWhite, i.CpuUtilization, escReset, - escBrightWhite, i.Threads, escReset, - escBrightWhite, i.PhyRSS, escReset, - escBrightWhite, i.VmSize, escReset, - escBrightWhite, i.Rchar, escReset, - escBrightWhite, i.Wchar, escReset, - ) - return result - //return fmt.Sprintf("name:%s pid:%s cpuUtilizetion:%f phyRss:%d vmRss:%d threadCount:%d readCharCount:%d writeCharCount:%d timeStamp:%d", i.Name, i.Pid, i.CpuUtilization, i.PhyRSS, i.VmSize, i.Threads, i.Rchar, i.Wchar, time.Now().Unix()) +func (i *ProcessInfo) ToString() string{ + return i.ToJson() } + +//func (i *ProcessInfo) ToString() string { +// +// var result = fmt.Sprintf( +// //%s%s%s%s up %s%s%s +// ` +//PID:%s%s%s Name:%s%s%s +// +//CPU: +// %s%.2f%s%% cpuUtilizetion +// %s%d%s ThreadCount +// +//Memory: +// physicalMemory = %s%d%s +// virtualMemory = %s%d%s +// +//`, +// escBrightWhite, i.Name, escReset, +// escBrightWhite, i.Pid, escReset, +// escBrightWhite, i.CpuUtilization, escReset, +// escBrightWhite, i.Threads, escReset, +// escBrightWhite, i.PhyRSS, escReset, +// escBrightWhite, i.VmSize, escReset, +// ) +// return result +// //return fmt.Sprintf("name:%s pid:%s cpuUtilizetion:%f phyRss:%d vmRss:%d threadCount:%d readCharCount:%d writeCharCount:%d timeStamp:%d", i.Name, i.Pid, i.CpuUtilization, i.PhyRSS, i.VmSize, i.Threads, i.Rchar, i.Wchar, time.Now().Unix()) +//} diff --git a/src/entity/system.go b/src/entity/system.go index c756e14..ba083ca 100644 --- a/src/entity/system.go +++ b/src/entity/system.go @@ -20,8 +20,6 @@ package entity import ( "encoding/json" "fmt" - "sort" - "time" ) type SystemFSInfo struct { @@ -62,96 +60,103 @@ type SystemCPUInfo struct { Guest float32 `json:"guest"` } -type SystemStats struct { - Uptime time.Duration `json:"uptime"` - Hostname string `json:"hostname"` - MemTotal uint64 `json:"memTotal"` - MemFree uint64 `json:"memFree"` - MemBuffers uint64 `json:"memBuffers"` - MemCached uint64 `json:"memCached"` - SwapTotal uint64 `json:"swapTotal"` - SwapFree uint64 `json:"swapFree"` - NetworkInfo map[string]*SystemNetworkInfo `json:"networkInfo"` - CPU map[string]*SystemCPUInfo `json:"cpu"` - TimeStamp int64 `json:"timeStamp"` +type SystemMemInfo struct { + MemTotal uint64 `json:"memTotal,omitempty"` + MemFree uint64 `json:"memFree,omitempty"` + MemBuffers uint64 `json:"memBuffers,omitempty"` + MemCached uint64 `json:"memCached,omitempty"` + MemUsage uint64 `json:"memUsage,omitempty"` + SwapTotal uint64 `json:"swapTotal,omitempty"` + SwapFree uint64 `json:"swapFree,omitempty"` } -func (stats *SystemStats) ToString() string { - used := stats.MemTotal - stats.MemFree - stats.MemBuffers - stats.MemCached - var result = fmt.Sprintf( - //%s%s%s%s up %s%s%s - ` -Memory: - free = %s%s%s - used = %s%s%s - buffers = %s%s%s - cached = %s%s%s - swap = %s%s%s free of %s%s%s - -`, - escBrightWhite, fmtBytes(stats.MemFree), escReset, - escBrightWhite, fmtBytes(used), escReset, - escBrightWhite, fmtBytes(stats.MemBuffers), escReset, - escBrightWhite, fmtBytes(stats.MemCached), escReset, - escBrightWhite, fmtBytes(stats.SwapFree), escReset, - escBrightWhite, fmtBytes(stats.SwapTotal), escReset, - ) - - if len(stats.CPU) > 0 { - result += "CPU:\n" - for k, v := range stats.CPU { - result += fmt.Sprintf("%s :%s%.2f%s%% user, %s%.2f%s%% sys, %s%.2f%s%% nice, %s%.2f%s%% idle, %s%.2f%s%% iowait, %s%.2f%s%% hardirq, %s%.2f%s%% softirq, %s%.2f%s%% guest\n", - k, - escBrightWhite, v.User, escReset, - escBrightWhite, v.System, escReset, - escBrightWhite, v.Nice, escReset, - escBrightWhite, v.Idle, escReset, - escBrightWhite, v.Iowait, escReset, - escBrightWhite, v.Irq, escReset, - escBrightWhite, v.SoftIrq, escReset, - escBrightWhite, v.Guest, escReset, - ) - } - result += "\n" - } +type SystemInfo struct { + MemInfo *SystemMemInfo `json:"memInfo,omitempty"` + NetworkInfo map[string]*SystemNetworkInfo `json:"networkInfo,omitempty"` + CPU map[string]*SystemCPUInfo `json:"cpu,omitempty"` + //TimeStamp int64 `json:"timeStamp"` +} - if len(stats.NetworkInfo) > 0 { - result += "Network Interfaces:\n" - keys := make([]string, 0, len(stats.NetworkInfo)) - for intf := range stats.NetworkInfo { - keys = append(keys, intf) - } - sort.Strings(keys) - for _, intf := range keys { - info := stats.NetworkInfo[intf] - result += fmt.Sprintf(" %s%s%s - %s%s%s", - escBrightWhite, intf, escReset, - escBrightWhite, info.IPv4, escReset, - ) - if len(info.IPv6) > 0 { - result += fmt.Sprintf(", %s%s%s\n", - escBrightWhite, info.IPv6, escReset, - ) - } else { - result += "\n" - } - result += fmt.Sprintf(" rx = %s%s%s, tx = %s%s%s\n", - escBrightWhite, fmtBytes(info.Rx), escReset, - escBrightWhite, fmtBytes(info.Tx), escReset, - ) - result += "\n" - } - result += "\n" - } - return result +func (stats *SystemInfo) ToString() string { + return stats.ToJson() } -func (stats *SystemStats) ToFormat() string { +//func (stats *SystemInfo) ToString() string { +// used := *stats.MemTotal - *stats.MemFree - *stats.MemBuffers - *stats.MemCached +// var result = fmt.Sprintf( +// //%s%s%s%s up %s%s%s +// ` +//Memory: +// free = %s%s%s +// used = %s%s%s +// buffers = %s%s%s +// cached = %s%s%s +// swap = %s%s%s free of %s%s%s +// +//`, +// escBrightWhite, fmtBytes(stats.MemInfo.MemFree), escReset, +// escBrightWhite, fmtBytes(stats.MemInfo.MemUsage), escReset, +// escBrightWhite, fmtBytes(stats.MemInfo.MemBuffers), escReset, +// escBrightWhite, fmtBytes(stats.MemInfo.MemCached), escReset, +// escBrightWhite, fmtBytes(stats.MemInfo.SwapFree), escReset, +// escBrightWhite, fmtBytes(stats.MemInfo.SwapTotal), escReset, +// ) +// +// if len(stats.CPU) > 0 { +// result += "CPU:\n" +// for k, v := range stats.CPU { +// result += fmt.Sprintf("%s :%s%.2f%s%% user, %s%.2f%s%% sys, %s%.2f%s%% nice, %s%.2f%s%% idle, %s%.2f%s%% iowait, %s%.2f%s%% hardirq, %s%.2f%s%% softirq, %s%.2f%s%% guest\n", +// k, +// escBrightWhite, v.User, escReset, +// escBrightWhite, v.System, escReset, +// escBrightWhite, v.Nice, escReset, +// escBrightWhite, v.Idle, escReset, +// escBrightWhite, v.Iowait, escReset, +// escBrightWhite, v.Irq, escReset, +// escBrightWhite, v.SoftIrq, escReset, +// escBrightWhite, v.Guest, escReset, +// ) +// } +// result += "\n" +// } +// +// if len(stats.NetworkInfo) > 0 { +// result += "Network Interfaces:\n" +// keys := make([]string, 0, len(stats.NetworkInfo)) +// for intf := range stats.NetworkInfo { +// keys = append(keys, intf) +// } +// sort.Strings(keys) +// for _, intf := range keys { +// info := stats.NetworkInfo[intf] +// result += fmt.Sprintf(" %s%s%s - %s%s%s", +// escBrightWhite, intf, escReset, +// escBrightWhite, info.IPv4, escReset, +// ) +// if len(info.IPv6) > 0 { +// result += fmt.Sprintf(", %s%s%s\n", +// escBrightWhite, info.IPv6, escReset, +// ) +// } else { +// result += "\n" +// } +// result += fmt.Sprintf(" rx = %s%s%s, tx = %s%s%s\n", +// escBrightWhite, fmtBytes(info.Rx), escReset, +// escBrightWhite, fmtBytes(info.Tx), escReset, +// ) +// result += "\n" +// } +// result += "\n" +// } +// return result +//} + +func (stats *SystemInfo) ToFormat() string { str, _ := json.MarshalIndent(stats, "", "\t") return string(str) } -func (stats *SystemStats) ToJson() string { +func (stats *SystemInfo) ToJson() string { str, _ := json.Marshal(stats) return string(str) } @@ -174,3 +179,14 @@ func fmtBytes(val uint64) string { return fmt.Sprintf("%6.2f GiB", float64(val)/1024.0/1024.0/1024.0) } } + +type PerfOption struct { + SystemCPU bool + SystemMem bool + SystemGPU bool + SystemNetWorking bool + ProcCPU bool + ProcFPS bool + ProcMem bool + ProcThreads bool +} diff --git a/src/perfmonUtil/process.go b/src/perfmonUtil/process.go index 31c28a1..3b2eae9 100644 --- a/src/perfmonUtil/process.go +++ b/src/perfmonUtil/process.go @@ -31,35 +31,8 @@ import ( "github.com/SonicCloudOrg/sonic-android-supply/src/adb" "github.com/SonicCloudOrg/sonic-android-supply/src/entity" - "github.com/goinggo/mapstructure" ) -func getIoDataOnPid(client *adb.Device, pid string) (*entity.ProcessIO, error) { - lines, err := client.OpenShell(fmt.Sprintf("/bin/cat /proc/%s/io", pid)) - if err != nil { - return nil, fmt.Errorf("exec command erro : " + fmt.Sprintf("/bin/cat /proc/%s/io", pid)) - } - data, err := ioutil.ReadAll(lines) - if err != nil { - log.Panic(err) - } - scanner := bufio.NewScanner(strings.NewReader(string(data))) - var ioMess = make(map[string]int) - for scanner.Scan() { - line := scanner.Text() - fields := strings.Fields(line) - value, err := strconv.Atoi(fields[1]) - if err != nil { - return nil, err - } - ioMess[strings.TrimRight(fields[0], ":")] = value - } - var io = &entity.ProcessIO{} - err = mapstructure.Decode(ioMess, io) - //fmt.Println(lines) - return io, nil -} - func getStatOnPid(client *adb.Device, pid string) (stat *entity.ProcessStat, err error) { lines, err := client.OpenShell(fmt.Sprintf("/bin/cat /proc/%s/stat", pid)) if err != nil { @@ -359,7 +332,7 @@ var sleepTime = 1.0 // # seconds var HZ = 100.0 //# ticks/second var cpuUtilization = 0.0 -func GetProcessInfo(client *adb.Device, pid string, name string, interval int64) (*entity.ProcessInfo, error) { +func GetProcessInfo(client *adb.Device, pid string, packageName string,perfOptions entity.PerfOption, interval int64) (*entity.ProcessInfo, error) { sleepTime = float64(interval) stat, err := getStatOnPid(client, pid) @@ -374,35 +347,41 @@ func GetProcessInfo(client *adb.Device, pid string, name string, interval int64) //if err != nil { // return nil, err //} - var processInfo entity.ProcessInfo - processInfo.PhyRSS = stat.Rss - processInfo.VmSize = stat.Vsize - if processInfo.Threads, err = strconv.Atoi(status.Threads); err != nil { - return nil, err + + if perfOptions.ProcThreads{ + var threads int + if threads, err = strconv.Atoi(status.Threads); err != nil { + return nil, err + } + processInfo.Threads = &threads } - getCpuUsage(client, pid) - processInfo.CpuUtilization = cpuUtilization + if perfOptions.ProcMem { + processInfo.PhyRSS = &stat.Rss + processInfo.VmSize = &stat.Vsize + } - //processInfo.ReadBytes = ioData.ReadBytes - //processInfo.WriteBytes = ioData.WriteBytes - processInfo.Name = status.Name - processInfo.Pid = status.Pid + if perfOptions.ProcCPU { + getCpuUsage(client, pid) + processInfo.CpuUtilization = &cpuUtilization + } - //processInfo.Rchar = ioData.Rchar - //processInfo.Wchar = ioData.Wchar - var fps = 0 - fps, err = getProcessFPSBySurfaceFlinger(client, name) + if perfOptions.ProcFPS{ + var fps = 0 - if fps <= 0 || err != nil { - fps, _ = getProcessFPSByGFXInfo(client, pid) - } + fps, err = getProcessFPSBySurfaceFlinger(client, packageName) - processInfo.FPS = fps + if fps <= 0 || err != nil { + fps, _ = getProcessFPSByGFXInfo(client, pid) + } - processInfo.TimeStamp = time.Now().Unix() + processInfo.FPS = &fps + } + + processInfo.Name = status.Name + processInfo.Pid = status.Pid return &processInfo, nil } diff --git a/src/perfmonUtil/system.go b/src/perfmonUtil/system.go index a249dae..8fdd13c 100644 --- a/src/perfmonUtil/system.go +++ b/src/perfmonUtil/system.go @@ -22,65 +22,42 @@ import ( "github.com/SonicCloudOrg/sonic-android-supply/src/adb" "github.com/SonicCloudOrg/sonic-android-supply/src/entity" "io" - "io/ioutil" "strconv" "strings" - "time" ) -func GetSystemStats(client *adb.Device) *entity.SystemStats { - stats := &entity.SystemStats{} - getAllStats(client, stats) - return stats -} - -func getAllStats(client *adb.Device, stats *entity.SystemStats) { - getUptime(client, stats) - getHostname(client, stats) - getMemInfo(client, stats) - getInterfaces(client, stats) - getInterfaceInfo(client, stats) - getCPU(client, stats) - stats.TimeStamp = time.Now().Unix() -} - -func getHostname(client *adb.Device, stats *entity.SystemStats) (err error) { - lines, err := client.OpenShell("/bin/hostname -f") - - if err != nil { - return - } - data, err := ioutil.ReadAll(lines) - if err != nil { - return +func GetSystemStats(client *adb.Device, perfOptions entity.PerfOption) (*entity.SystemInfo, error) { + stats := &entity.SystemInfo{} + var err error + if perfOptions.SystemCPU { + err = getCPU(client, stats) + if err != nil { + return nil, err + } } - stats.Hostname = strings.TrimSpace(string(data)) - return -} -func getUptime(client *adb.Device, stats *entity.SystemStats) (err error) { - lines, err := client.OpenShell("/bin/cat /proc/uptime") - if err != nil { - return - } - uptime, err := ioutil.ReadAll(lines) - if err != nil { - return - } - parts := strings.Fields(string(uptime)) - if len(parts) == 2 { - var upsecs float64 - upsecs, err = strconv.ParseFloat(parts[0], 64) + if perfOptions.SystemMem { + stats.MemInfo = &entity.SystemMemInfo{} + err = getMemInfo(client, stats) if err != nil { - return + return nil, err } - stats.Uptime = time.Duration(upsecs * 1e9) } - return + if perfOptions.SystemNetWorking { + err = getInterfaces(client, stats) + if err != nil { + return nil, err + } + err = getInterfaceInfo(client, stats) + if err != nil { + return nil, err + } + } + return stats, nil } -func getMemInfo(client *adb.Device, stats *entity.SystemStats) (err error) { +func getMemInfo(client *adb.Device, stats *entity.SystemInfo) (err error) { lines, err := client.OpenShell("/bin/cat /proc/meminfo") if err != nil { return @@ -98,24 +75,25 @@ func getMemInfo(client *adb.Device, stats *entity.SystemStats) (err error) { val *= 1024 switch parts[0] { case "MemTotal:": - stats.MemTotal = val + stats.MemInfo.MemTotal = val case "MemFree:": - stats.MemFree = val + stats.MemInfo.MemFree = val case "Buffers:": - stats.MemBuffers = val + stats.MemInfo.MemBuffers = val case "Cached:": - stats.MemCached = val + stats.MemInfo.MemCached = val case "SwapTotal:": - stats.SwapTotal = val + stats.MemInfo.SwapTotal = val case "SwapFree:": - stats.SwapFree = val + stats.MemInfo.SwapFree = val } } } + stats.MemInfo.MemUsage = stats.MemInfo.MemTotal - stats.MemInfo.MemFree - stats.MemInfo.MemBuffers - stats.MemInfo.MemCached return } -func getInterfaces(client *adb.Device, stats *entity.SystemStats) (err error) { +func getInterfaces(client *adb.Device, stats *entity.SystemInfo) (err error) { var lines io.ReadCloser lines, err = client.OpenShell("/bin/ip -o addr") if err != nil { @@ -159,7 +137,7 @@ func getInterfaces(client *adb.Device, stats *entity.SystemStats) (err error) { return } -func getInterfaceInfo(client *adb.Device, stats *entity.SystemStats) (err error) { +func getInterfaceInfo(client *adb.Device, stats *entity.SystemInfo) (err error) { lines, err := client.OpenShell("/bin/cat /proc/net/dev") if err != nil { return @@ -230,7 +208,7 @@ func parseCPUFields(fields []string, stat *entity.SystemCpuRaw) { var preCPU entity.SystemCpuRaw var preCPUMap map[string]entity.SystemCpuRaw -func getCPU(client *adb.Device, stats *entity.SystemStats) (err error) { +func getCPU(client *adb.Device, stats *entity.SystemInfo) (err error) { lines, err := client.OpenShell("/bin/cat /proc/stat") if err != nil { return