296 lines (263 sloc) 12.2 KB
#/user/bin/python
#encoding:utf-8

import os
import time
import csv

import subprocess
import re
import easygui as g
import sys

si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
‘’’
本脚本实现的为:在某一测试场景下,监控APP的专项数据:“CPU”, “内存”, “电量”, “流量”
专项数据分析:
CPU:
在一个时间段如20分钟cpu在40%稳定,是在可接受范围内的。
若一直在80%以上,就是有问题的。
内存:
连续测试两个小时,看内存变化的曲线范围,如果有几百M的范围波动变化,就需要关注跟踪问题
电量:
设定一个场景,在半个小时查看手机电量消耗情况,短时间无法取到可供参考分析的值
流量:
eth0和eth1是两个网卡,两个网卡和就是流量值
将最后一次的值减去第一次值获得操作后的消耗流量
1. 与竞品进行分析 – 消耗流量多需分析
2. 历史版本比较分析
v1.2 20M
v1.3 30M
‘’’

‘’’
adb shell top可选的参数如下:
-m num Maximum number of processes to display. 最多显示多少个进程
-n num Updates to show before exiting. 刷新次数
-d num Seconds to wait between updates. 刷新间隔时间(默认5秒)
-s col Column to sort by (cpu,vss,rss,thr). 按哪列排序
-t Show threads instead of processes. 显示线程信息而不是进程
-h Display this help screen. 显示帮助文档

adb命令如下:
adb shell top -n 1|findstr com.xiaomi.shop

‘’’

控制类

class Controller(object):
def init(self, count):
self.counter = count
self.alldata = [(“timestamp”, “CPU”, “内存”, “电量”, “流量”, “pid”, “uid”, “CPU异常信息”, “内存异常信息”, “activity”)]
self.cpuvalue = “” # cpu
self.memvalue = “” # 内存
self.power = “” # 电量
self.receive = 1 # 收到
self.transmit = 1 # 传输
self.receive2 = 1
self.transmit2 = 1
self.activity = “” # activity
self.pid = “” # pid
self.uid = “” # uid
self.max_cpu = 70 # cpu预警值
self.max_mem = 300 # mem预警值
self.abnormal_cpu_msg = “” # cpu异常信息
self.abnormal_mem_msg = “” # mem异常信息
self.msg = g.enterbox(msg=“请输入你要监控的使用场景”, title=“监控APP专项数据”)
# 输入包名
self.appPackage = “com.xiaomi.shop”
# self.appPackage = “cn.art.app”

# 获取当前设备名
def get_devices(self):devices = []result = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE).stdout.readlines()# print(result[1].decode())# print(">>>命令结果 len(result)" + str(len(result)))if len(result) - 2 == 1:for line in result[1:]:devices.append(line.strip().decode())print("当前设备名为: " + str(devices[0].split()[0]))return devices[0].split()[0]else:# 如果没有设备弹窗提示,并退出程序g.msgbox(image='Warning.gif', msg="当前没有移动设备或不止一个设备!!!")sys.exit(0)return devices[0]# 获取包名
def getpackagename(self):pattern = re.compile(r"[a-zA-Z0-9\.]+/.[a-zA-Z0-9\.]+")package = subprocess.Popen("adb shell dumpsys activity | findstr  mFocusedActivity", shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read()package = (str(package))packagename = pattern.findall(package)[0].split('/')[0]print("测试app包名为: " + str(packagename))return packagename# 获取activity
def getactivity(self):pattern = re.compile(r"[a-zA-Z0-9\.]+/.[a-zA-Z0-9\.]+")package = subprocess.Popen("adb shell dumpsys activity | findstr  mFocusedActivity", shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read()package = (str(package))activity = pattern.findall(package)[0].split('/')[1]print("当前操作activity包名为: " + str(activity))return activity# 获取pid
# PID是进程的身份标识,程序一旦运行,就会给应用分配一个独一无二的PID
def get_pid(self):pid_list = []cmd = 'adb -s ' + self.get_devices() + ' shell ps |findstr ' + self.getpackagename()pid_info = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()if len(pid_info) >= 1:pid_list.append(int(pid_info[0].split()[1]))return str(pid_list[0])# 获取uid
# UID 指用户ID 为了实现数据共享,android为每个应用几乎都分配了不同的UID,不像传统的linux,每个用户相同就为之分配相同的UID
def get_uid(self):uid_list = []cmd = 'adb -s ' + self.get_devices() + ' shell cat  /proc/' + self.get_pid() + '/status'uid_info = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()if len(uid_info) >= 1:uid_list.append(int(uid_info[6].split()[1]))return str(uid_list[0])# 百分数转为int
def percent_to_int(self,string):if "%" in string:newint = int(string.strip("%")) / 100return newintelse:print("你输入的不是百分比!")# 单次测试过程
def testprocess(self):# 获取pid和uidself.pid = self.get_pid()self.uid = self.get_uid()# 获取CPUresult = os.popen('adb shell "dumpsys cpuinfo | grep com.xiaomi.shop"')# result = os.popen('adb shell "dumpsys cpuinfo | grep cn.art.app"')for line in result.readlines():self.cpuvalue = line.split("%")[0]break  # 若找出多个内存占用值,取第一个取到就停止,否则会取到最后的0# 如果cpu超过预警值 提示if float(self.cpuvalue) > self.max_cpu:# print("cpu爆表啦,快去看看" + str(self.cpuvalue))# 记录异常信息self.abnormal_cpu_msg = "当前cpu值超过预警值" + str(self.max_cpu) + "%"# CPU超过预警就记录当前activityself.activity = self.getactivity()# 获取内存和cpu(cpu已去除)# result = os.popen("adb shell top -n 1|findstr com.xiaomi.shop")result = os.popen("adb shell top -n 1|findstr %s" %self.appPackage)for line in result.readlines():if "fg" in line:# 将所有空行换成#line = "#".join(line.split())# self.cpuvalue = line.split("#")[2]# self.cpuvalue = self.percent_to_int(self.cpuvalue)# print("统一命令获取的CPU  " + str(self.cpuvalue))# # 如果cpu超过预警值 提示# if self.cpuvalue > self.max_cpu:#     print("cpu爆表啦,快去看看" + str(self.cpuvalue))#     self.activity = self.getactivity()#     print("activity>>>>>" + str(self.activity))self.mem = line.split("#")[6]self.memvalue = str(round(int(self.mem[:-1]) / 1024))# print(">>>self.memvalue: " + self.memvalue)if int(round(int(self.mem[:-1]) / 1024)) > self.max_mem:# CPU超过预警就记录当前activityself.activity = self.getactivity()# 记录mem异常信息self.abnormal_mem_msg = "当前mem值超过预警值" + str(self.max_mem) + "M"# 手机连接到电脑,默认为充电状态# 切换手机电池为非充电状态  --2 为充电状态os.popen("adb shell dumpsys battery set status 1")# 执行获取电量的命令powerData = os.popen("adb shell dumpsys battery")# 获取电量的levelfor line in powerData:if "level" in line:# 格式化电量值--去除换行self.power = line.split(":")[1].replace("\n", "")# 小米商城 --# result = os.popen('adb shell "ps | grep com.xiaomi.shop"')result = os.popen('adb shell "ps | grep %s"'%self.appPackage)# 获取进程IDpid = result.readlines()[0].split(" ")[4]# print(">>>>>pid: " + str(pid))# 获取进程ID使用的流量traffic = os.popen("adb shell cat /proc/" + pid + "/net/dev")for line in traffic:if "eth0" in line:# 将所有空行换成#line = "#".join(line.split())# 按#号拆分,获取收到和发出的流量self.receive = line.split("#")[1]print("receive为:" + str(self.receive))self.transmit = line.split("#")[9]print("transmit为:" + str(self.transmit))elif "eth1" in line:# 将所有空行换成#line = "#".join(line.split())# 按#号拆分,获取收到和发出的流量self.receive2 = line.split("#")[1]# print("222receive2为:" + str(self.receive2))self.transmit2 = line.split("#")[9]# print("222transmit为:" + str(self.transmit2))# 计算所有流量之和alltraffic = int(self.receive) + int(self.transmit) + int(self.receive2) + int(self.transmit2)# print("所有流量之和为: " + str(alltraffic))# 按KB计算流量值alltraffic = alltraffic / 1024alltraffic = alltraffic / 1024# 保留小数点后两位alltraffic = round(alltraffic, 2)alltraffic = str(alltraffic)# 获取当前时间currenttime = self.getCurrentTime()# 将获取到的数据存到数组中self.alldata.append((currenttime, self.cpuvalue, self.memvalue, self.power, alltraffic, self.pid, self.uid, self.abnormal_cpu_msg, self.abnormal_mem_msg, self.activity))# print(">>>>>cpuvalue " + self.cpuvalue)# print(">>>>>mem " + self.mem)# print(">>>>>memvalue " + self.memvalue)# print(">>>>>power " + self.power)# print(">>>>>消耗流量为: " + str(alltraffic))# 多次执行测试过程
def run(self):# 当执行次数大于0则执行单次测试过程,并次数-1while self.counter > 0:self.testprocess()self.counter = self.counter - 1time.sleep(3)# 获取当前的时间戳
def getCurrentTime(self):currentTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())return currentTime# 数据的存储
def SaveDataToCSV(self):# 获取当前时间 可确保测试报告文件不重名now = time.strftime("%Y-%m-%d %H_%M_%S")csvName = "【" + self.msg + "】" + now + ' APPstatus.csv'# 定义一个csv文件 --记录数据csvfile = open(csvName, 'w', newline='')writer = csv.writer(csvfile)# 写数据writer.writerows(self.alldata)csvfile.close()

if name == ‘main’:
# 存入程序开始时间
start = time.clock()

# 实例化controller类 并执行20次  20次-140秒
controller = Controller(20)
# 获取当前系统是否有且只有一个移动设备
controller.get_devices()
# 如果上述不是一个移动设备,系统退出# 获取监控app的包名
controller.getpackagename()
# 获取监控app的activity
controller.getactivity()# 跑起来
controller.run()
# 数据的存储
controller.SaveDataToCSV()
# 避免等待,提前告知结束
g.msgbox("代码运行结束了!", image='Warning.gif')# 测试完后切换手机电池为充电状态  --2 为充电状态
os.popen("adb shell dumpsys battery set status 2")
print("已切换回充电模式...")# 存入结束时间
end = time.clock()

print(“整个测试总共花费了 %.1f 秒” % (end - start))

脚本实现监控APP的专项数据:CPU 内存 电量 流量相关推荐

  1. 【Android真机app的性能测试(CPU,内存,启动时间)】

    Android真机app的性能测试(CPU,内存占用,启动时间) 查看app启动时间 查看app的内存占用情况 查看app的CPU占用情况 查看app启动时间 与设备进行adb连接后,输入命令 adb ...

  2. zabbix监控项配置—带宽/磁盘/CPU/内存/IIS/事件日志

    目录 一.主机连接 二.目前模板配置 (一)DaiKuan (二)disk warning (三)Template App IIS by Zabbix agent (四)Template OS Win ...

  3. Linux 查看CPU 内存 IO使用率,linux 查看CPU内存 网络 流量 磁盘 IO

    使用vmstat命令来察看系统资源情况 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? Q: 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? A: 在命 ...

  4. 如何查看linux网络io,linux 查看CPU内存 网络 流量 磁盘 IO

    使用vmstat命令来察看系统资源情况 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? Q: 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? A: 在命 ...

  5. Linux系统监控命令整理汇总-掌握CPU,内存,磁盘IO等找出性能瓶颈

    的性能有问题,总之,每到晚上挖站否的主机就出现了不稳定的情况,系统负载忽高忽低.利用服务器日志分析利器:ngxtop和GoAccess也能查出有一些IP一直在不断地扫描服务器端口还有WP后台. 但是, ...

  6. linkedin databus介绍——监听数据库变化,有新数据到来时通知其他消费者app,新数据存在内存里,多份快照...

    概要结构如下图. 图中显示:Search Index和Read Replicas等系统是Databus的消费者.当主OLTP数据库发生写操作时,连接其上的中继系统会将数据拉到中继中.签入在Search ...

  7. android pc 状态 监测,简简单单就是美 简约风状态监控App体验

    安卓用起来和Windows十分相似,不少朋友也将Windows平台的习惯带到了安卓上--比如说整天盯着任务管理器看.安卓上的状态监控App为数不少,什么CPU.内存的运行都可以看得一清二楚.不过这类如 ...

  8. 【app性能测试】Python脚本监控app指标

    1. adb shell top top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最"敏感"的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序. ...

  9. App性能分析数据监控

    App性能分析数据监控 APP的性能监控包括: CPU 占用率.内存使用情况.网络状况监控.启动时闪退.卡顿.FPS.使用时崩溃.耗电量监控.流量监控等等. 文中所有代码都已同步到github中,有兴 ...

最新文章

  1. puppet运维自动化之yum仓库管理
  2. 微信自定义分享卡片链接的解决方案(可自定义标题 描述 图片)
  3. 有一种爱,永远也无法逾越
  4. 如何打开python的交互窗口-Python多版本情况下四种快速进入交互式命令行的操作技巧...
  5. element菜单默认展开和选中
  6. spring servlet 扩展undertow
  7. Linux文件系统命令 cat
  8. 最新解决ora-01034:oracle not available 的方法
  9. Windows-Server下加强系统安全性系列之方案【六】
  10. mysql dml原理_InnoSQL/MySQL DML Flashback功能简介
  11. CAS 4.1.x 单点登出(退出登录)的原理解析
  12. Java中Double保留六位小数_Java中Double保留后小数位的几种方法
  13. VMware16的下载安装及搭建Linux环境
  14. 新版百度网盘公测,真不限速了
  15. 洛谷P1792 [国家集训队]种树 题解
  16. mysql 内联注释_TSRC挑战赛:WAF之SQL注入防御思路分享
  17. [CF 417D]Cunning Gena:状压DP
  18. SpringCloud(part10)Spring Data 与JPA,MongoDB,Redis
  19. 记录ant design vue a-select Form编辑时回显数据库数据为value而不是label的问题
  20. 如何用好示波器?资深工程师也会忽略这些细节……

热门文章

  1. 小程序中使用loading组件显示正在加载
  2. 基于JAVA网上求职招聘系统计算机毕业设计源码+数据库+lw文档+系统+部署
  3. 网工协议基础(5)ARP协议
  4. 周纵苇——三维迁移学习报告笔记
  5. 常用设计模式C++实现(一)
  6. 「上层建筑」与「结构基础」~不被迷惑
  7. linux用mail往qq邮箱发邮件
  8. HAL库学习之高级定时器输出PWM
  9. Multi-Threshold Byzantine Fault Tolerance (CCS 2021)
  10. Quartus ii 软件的使用