Android性能监控小工具
2017-02-23 08:41
316 查看
//编译方法如下:
//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共享库,确保该共享库位于链接路径中
//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 <stdio.h> #include <stdlib.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <time.h> #include <fcntl.h> #include <string.h> #include <dirent.h> #include <unistd.h> #include <vector> #include <string> // 更新周期,单位微妙,即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); // ma 4000 jflt 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; // 打开文件夹/proc d = 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'/cmdline fd = open(cmdline, O_RDONLY); if(fd == 0) { r = 0; } else { // 读取文件/proc/'tmp_pid'/cmdline r = 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<std::string>& 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/stat fd = open(fileline, O_RDONLY); if(fd == 0) { r = 0; } else { // 读取文件/proc/stat到content r = read(fd, content, 1024 - 1); close(fd); } content[r] = 0; // 对content进行分割 std::vector<std::string> 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/stat fd = open(fileline, O_RDONLY); if(fd == 0) { r = 0; } else { // 读取文件/proc/pid/stat到content r = read(fd, content, 1024 - 1); close(fd); } content[r] = 0; // 对content进行分割 std::vector<std::string> 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 <unistd.h> 单位:微秒(us)(百万分之一秒) usleep(UPDATE_PERIOD); } if (flog) fclose(flog); }
相关文章推荐
- Android进程性能监控工具Honeybadger实现
- Android性能测试:CPU内存监控工具APT
- Android的性能监控工具StrictMode
- android app性能监控工具,同时支持monkey测试
- Android 性能测试实践(二) 实时监控工具
- Android进程性能监控工具Honeybadger实现
- Android 性能测试实践(二) 实时监控工具
- Android 性能测试实践(二) 实时监控工具
- 使用测试工具iPerf监控无线网络性能
- JProfiler(Java 性能监控工具)
- 使用测试工具iPerf监控无线网络性能
- Android 联网监控抓包工具的制作(tcpdump的使用)
- tomcat性能监控工具 lambda probe
- Linux系统整体性能监控工具详解
- 性能测试工具、监控工具
- Linux下面监控系统性能的工具-vmstat
- Linux下性能监控工具介绍
- Jwebap项目——性能监控工具Jwebap: 0.5.8(转)
- 性能监控工具
- Linux系统整体性能监控工具详解