Android性能监控小工具

//编译方法如下:

//d:\android-ndk-r8e-windows-x86\android-ndk-r8e为Android NDK根目录

cd d:\android-ndk-r8e-windows-x86\android-ndk-r8e\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\

arm-linux-androideabi-g++.exe -fPIE -pie -fpermissive --sysroot=d:\android-ndk-r8e-windows-x86\android-ndk-r8e\platforms\android-9\arch-arm\ -I d:\android-ndk-r8e-windows-x86\android-ndk-r8e\sources\cxx-stl\stlport\stlport\ -l d:\android-ndk-r8e-windows-x86\android-ndk-r8e\sources\cxx-stl\stlport\libs\armeabi-v7a\libstlport_shared.so e:\itrans\osres_mon_android.cpp -o e:\itrans\osres_mon_android 1>stdout 2>&1

//简略为:g++ -fPIE -pie --sysroot="" -I"\stlport" -l"libstlport_shared.so" osres_mon_android.cpp -o osres_mon_android

//运行方法:

//需依赖libstlport_shared.so共享库,确保该共享库位于链接路径中

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #include 
#include // 更新周期,单位微妙,即1秒
#define UPDATE_PERIOD 1000000
#define CALC_FACTOR (1E8/UPDATE_PERIOD)static char *nexttoksep(char **strp, char *sep)  
{  char *p = strsep(strp,sep);  return (p == 0) ? "" : p;  
}  
static char *nexttok(char **strp)  
{  return nexttoksep(strp, " ");  
}  
static int ps_line(int pid, unsigned int& ret_vsize, unsigned int& ret_rss)  
{  char statline[1024];  char user[32];  struct stat stats;  int fd, r;  char *ptr, *name, *state;  int ppid, tty;  unsigned wchan, rss, vss, eip;  unsigned utime, stime;  int prio, nice, rtprio, sched;  struct passwd *pw;  sprintf(statline, "/proc/%d", pid);  stat(statline, &stats);  sprintf(statline, "/proc/%d/stat", pid);fd = open(statline, O_RDONLY);  if(fd == 0) return -1;  r = read(fd, statline, 1023);  close(fd);  if(r < 0) return -1;  statline[r] = 0;  ptr = statline;  nexttok(&ptr); // skip pid  ptr++;          // skip "("  name = ptr;  ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',  *ptr++ = '\0';           // and null-terminate name.  ptr++;          // skip " "  state = nexttok(&ptr);  ppid = atoi(nexttok(&ptr));  nexttok(&ptr); // pgrp  nexttok(&ptr); // sid  tty = atoi(nexttok(&ptr));  nexttok(&ptr); // tpgid  nexttok(&ptr); // flags  nexttok(&ptr); // minflt  nexttok(&ptr); // cminflt  nexttok(&ptr); // majflt  nexttok(&ptr); // cmajflt  
#if 1  utime = atoi(nexttok(&ptr));  stime = atoi(nexttok(&ptr));  
#else  nexttok(&ptr); // utime  nexttok(&ptr); // stime  
#endif  nexttok(&ptr); // cutime  nexttok(&ptr); // cstime  prio = atoi(nexttok(&ptr));  nice = atoi(nexttok(&ptr));  nexttok(&ptr); // threads  nexttok(&ptr); // itrealvalue  nexttok(&ptr); // starttime  vss = strtoul(nexttok(&ptr), 0, 10); // vsize  rss = strtoul(nexttok(&ptr), 0, 10); // rss  nexttok(&ptr); // rlim  nexttok(&ptr); // startcode  nexttok(&ptr); // endcode  nexttok(&ptr); // startstack  nexttok(&ptr); // kstkesp  eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip  nexttok(&ptr); // signal  nexttok(&ptr); // blocked  nexttok(&ptr); // sigignore  nexttok(&ptr); // sigcatch  wchan = strtoul(nexttok(&ptr), 0, 10); // wchan  nexttok(&ptr); // nswap  nexttok(&ptr); // cnswap  nexttok(&ptr); // exit signal  nexttok(&ptr); // processor  rtprio = atoi(nexttok(&ptr)); // rt_priority  sched = atoi(nexttok(&ptr)); // scheduling policy  tty = atoi(nexttok(&ptr));  //pw = getpwuid(stats.st_uid);  //if(pw == 0) {  //    sprintf(user,"%d",(int)stats.st_uid);  //} else {  //    strcpy(user,pw->pw_name);  //}  ret_vsize = vss / 1024;ret_rss = rss * 4;return 0;
}  unsigned long get_pid_from_cmd(char* cmd_name)
{int pid = -1;DIR *d;struct dirent *de;char cmdline[1024];int fd,r,tmp_pid;// 打开文件夹/procd = opendir("/proc");if(d == 0) return -1;// 遍历/proc下的子文件夹while((de = readdir(d)) != 0){if(isdigit(de->d_name[0])){// 如果文件夹名中含有数字,则可能是某个进程tmp_pid = atoi(de->d_name);sprintf(cmdline, "/proc/%d/cmdline", tmp_pid);// 打开文件/proc/'tmp_pid'/cmdlinefd = open(cmdline, O_RDONLY);  if(fd == 0) {r = 0;} else {// 读取文件/proc/'tmp_pid'/cmdliner = read(fd, cmdline, 1023);close(fd);}cmdline[r] = 0;// cmdline长度不为零,且cmd_name为其子串if (0 != strlen(cmdline) && NULL != strstr(cmdline, cmd_name)){pid = tmp_pid;break;}}}closedir(d);
}// 字符串分割
void SplitString(const std::string& s, std::vector& v, const std::string& c)
{std::string::size_type pos1, pos2;pos2 = s.find(c);pos1 = 0;while(std::string::npos != pos2){v.push_back(s.substr(pos1, pos2-pos1));pos1 = pos2 + c.size();pos2 = s.find(c, pos1);}if(pos1 != s.length())v.push_back(s.substr(pos1));
}
static unsigned long getTotalCpuTime()
{// 获取系统总CPU使用时间char fileline[1024]={0};char content[1024]={0};int fd,r;sprintf(fileline, "/proc/stat");// 打开文件/proc/statfd = open(fileline, O_RDONLY);  if(fd == 0) {r = 0;} else {// 读取文件/proc/stat到contentr = read(fd, content, 1024 - 1);close(fd);}content[r] = 0;// 对content进行分割std::vector cpuInfos;SplitString(content, cpuInfos, " ");if (cpuInfos.size() >= 9) {unsigned long totalCpuTime = atol(cpuInfos[2].c_str())+ atol(cpuInfos[3].c_str()) + atol(cpuInfos[4].c_str())+ atol(cpuInfos[6].c_str()) + atol(cpuInfos[5].c_str())+ atol(cpuInfos[7].c_str()) + atol(cpuInfos[8].c_str());return totalCpuTime;}else{return 0;}
}
static unsigned long getAppCpuTime(int pid)
{// 获取应用占用的CPU时间char fileline[1024]={0};char content[1024]={0};int fd,r;sprintf(fileline, "/proc/%d/stat", pid);// 打开文件/proc/pid/statfd = open(fileline, O_RDONLY);  if(fd == 0) {r = 0;} else {// 读取文件/proc/pid/stat到contentr = read(fd, content, 1024 - 1);close(fd);}content[r] = 0;// 对content进行分割std::vector cpuInfos;SplitString(content, cpuInfos, " ");if (cpuInfos.size() >= 17) {unsigned long appCpuTime = atol(cpuInfos[13].c_str())+ atol(cpuInfos[14].c_str()) + atol(cpuInfos[15].c_str())+ atol(cpuInfos[16].c_str());return appCpuTime;}else{return 0;}
}static float getProcessCpuRate(int pid)
{unsigned long totalCpuTime1 = getTotalCpuTime();unsigned long processCpuTime1 = getAppCpuTime(pid);usleep(UPDATE_PERIOD);unsigned long totalCpuTime2 = getTotalCpuTime();unsigned long processCpuTime2 = getAppCpuTime(pid);if(!totalCpuTime1 || !processCpuTime1 || !totalCpuTime2 || !processCpuTime2)return 0.0f;float cpuRate = 100 * (processCpuTime2 - processCpuTime1)/ (totalCpuTime2 - totalCpuTime1);return cpuRate;
}int main(int argc, char * argv[])
{char cmd[100] = "itranscon";unsigned long pid = -1;unsigned int vsize = 0;unsigned int rss = 0;float cpu_rate = 0.0f;time_t t;if (argc < 2){printf("Usage: osres_mon command\n");printf("Monitoring default process:itranscon!\n");}else{strcpy(cmd,argv[1]);}pid =  get_pid_from_cmd(cmd);if (pid == -1){printf("Not find pid named %s\n",cmd);return -1;}FILE* flog = NULL;flog = fopen("osres_mon.log", "w+");if(!flog) {printf("open log file failed!\n");}printf("PID COMMAND VSIZE RSS CPU_RATE TIME\n");if (flog) {fprintf(flog, "PID COMMAND VSIZE RSS CPU_RATE TIME\n");fflush(flog);}//PID 进程ID//COMMAND 进程名称//VSIZE 进程的虚拟内存大小,以KB为单位//RSS 进程实际占用的内存大小,以KB为单位//CPU_RATE 进程的CPU使用率while (true){if (0 != ps_line(pid, vsize, rss)) {printf("ps_line() error!\n");return -1;}cpu_rate = getProcessCpuRate(pid);t = time(NULL);printf("%d\t%s\t%d\t%d\t%.3f%%\t%s\t",pid,cmd,vsize,rss,cpu_rate,asctime(localtime(&t)));if (flog) {fprintf(flog, "%d\t%s\t%d\t%d\t%.3f%%\t%s\t",pid,cmd,vsize,rss,cpu_rate,asctime(localtime(&t)));fflush(flog);}// usleep  单位:微秒(us)(百万分之一秒)usleep(UPDATE_PERIOD);}if (flog)fclose(flog);
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部