手機實時cpu佔用率檢視(監測cpu佔用率的軟體)
實時監控記憶體、CPU消耗工具
1.概述
通過工具,將能夠根據需要監控CPU、記憶體狀態。指令碼預設每隔10s鍾獲取一次當前的cpu、記憶體狀態並記錄,設定的時間到了後,停止獲取並開始分析資料,最後自動發出結果郵件。執行結果截圖如下
2.使用介紹
2.1使用場景
在手工測試APP的時候,可同步監測系統、該app的效能
在做自動化測試的時候,可同步監測系統、指定的apps的效能
在做Monkey測試的時候,可同步監測系統、指定的apps的效能
2.2執行環境
2.2.1 .ubuntu系統,安裝好python2.7、adb工具,pychart外掛
2.2.2 手機需要支援top、procrank命令
2.3使用方法:
2.3.1根據需要修改systemMonitor.conf配置檔案,配置項有:
[runTime]#腳步執行時長,以分鐘為單位
rumTime=1
[updateTime]#重新整理間隔,預設為10秒
updateTime=10
[packageNameList]#過濾程序名,多個程序以逗號分隔
packageNameList=com.android.email,com.android.providers.calendar,
[mailto_list]#收件人,以逗號分隔
mailto_list= ***@163.com
[mailInfo]#郵件伺服器引數
mailserver=***
user=***
password=*********
2.3.2執行指令碼
python systemMonitor.py
3.實際程式碼
分為三個檔案,下面將逐個展現。
3.1 systemMonitor.conf
[runTime]#執行時長,以分鐘為單位
rumTime=10
[updateTime]#重新整理間隔,預設為10秒
updateTime=10
[packageNameList]#過濾程序名,多個程序以逗號分隔
packageNameList=com.android.providers.calendar,
[mailto_list]#收件人,以逗號分隔
mailto_list=***@163.com
[mailInfo]#郵件伺服器引數
mailserver=***
user=***
password=***
me=***@163.com
3.2 systemMonitor.py
#encoding:utf-8
import os
import sys
import datetime
from threading import Thread
import threading
import subprocess
import ConfigParser
from analysisInfo import *
from pychartdir import *
import smtplib
from email.mime.image import MIMEImage
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
import time
def getTime():
now = datetime.datetime.now()
return now.strftime("%Y-%m-%d %H:%M:%S")
def run_cmd(cmd):
process = subprocess.Popen(cmd , shell = True, stdout=subprocess.PIPE)
return process.stdout.read().strip()
def timestamp_datetime(value):
value = time.localtime(value)
dt = time.strftime('%Y-%m-%d %H:%M:%S', value)
return dt
#獲取裝置型號
def get_model():
return run_cmd('adb shell getprop ro.product.model')
#獲取Android版本
def get_androidVersion():
return run_cmd('adb shell getprop ro.build.version.release')
#獲取CPU型號
def get_cpuInfo():
return run_cmd('adb shell getprop ro.product.cpu.abi')
#獲取系統編譯版本增量
def get_buildVersionIncremental():
return run_cmd('adb shell getprop ro.build.version.incremental')
#獲取系統編譯時間
def get_buildDate():
return run_cmd('adb shell getprop ro.build.date.utc')
#生成表
#title:標題
#lable:
#ytitle
#data
#chartpath
#title_list
#style
def get_chart(title,label,ytitle,data,chartpath,title_list,style):
color_list = [0x008800,0xff0000,0x8A2BE2,0xA52A2A,0x7FFF00,0xFF7F50,0xDC143C,0x8B008B,0xFF1493,0xFFD700]
c = XYChart(1400, 600, 0xCCEEFF, 0x000000, 1)
c.addTitle(title, "simsun.ttc", 18).setBackground(0xCCEEFF, 0x000000, glassEffect())
c.setPlotArea(50, 55, 1300, 500)
c.addLegend(50, 28, 0, "arialbd.ttf", 10).setBackground(Transparent)
c.xAxis().setLabels(label)
c.yAxis().setTickDensity(30)
c.xAxis().setLabelStyle("arialbd.ttf", 8)
c.yAxis().setLabelStyle("arialbd.ttf", 8)
c.xAxis().setWidth(2)
c.yAxis().setWidth(2)
c.yAxis().setTitle(ytitle, "arialbd.ttf", 10)
layer = c.addLineLayer2()
layer.setLineWidth(3)
#c.addText(1280, 70,"最大值:111/n最小值:111").setAlignment(BottomRight)
for i in range(0,len(data)):
layer.addDataSet(data[i], color_list[i],title_list[i]).setDataSymbol(CircleShape, 1)
#layer.setDataLabelStyle("",10)
#layer.setDataLabelFormat(None)
c.setDefaultFonts("simsun.ttc")
c.makeChart(chartpath)
#傳送郵件
def send_mail_image(mailserver,user,password,me,mailto_list,title,bodyinfo,system_file_list,system_maxminavg,appInfo_list,app_file_list):
msg = MIMEMultipart('related')
msg['Subject']=title
msg['From']=me
msg['To']=';'.join(mailto_list)
content = ""
content =""
content =""
content =""
content =""
content =""
content =""
content ="執行時長(分):".decode('UTF-8').encode('GBK') str(bodyinfo[9]) ""
content = "
"
content ="開始時間:".decode('UTF-8').encode('GBK') bodyinfo[0] ""
content = "
"
content ="結束時間:".decode('UTF-8').encode('GBK') bodyinfo[1] ""
content = "
"
content ="重新整理次數:".decode('UTF-8').encode('GBK') str(bodyinfo[2]) ""
content = "
"
content ="重新整理頻率(秒):".decode('UTF-8').encode('GBK') str(bodyinfo[3]) ""
content = "
"
content ="裝置名稱:".decode('UTF-8').encode('GBK') str(bodyinfo[4]) ""
content = "
"
content ="系統版本:".decode('UTF-8').encode('GBK') str(bodyinfo[5]) ""
content = "
"
content ="CPU資訊:".decode('UTF-8').encode('GBK') str(bodyinfo[6]) ""
content = "
"
content ="系統編譯增量:".decode('UTF-8').encode('GBK') str(bodyinfo[7]) ""
content = "
"
content ="系統編譯日期:".decode('UTF-8').encode('GBK') str(bodyinfo[8]) ""
content = "
"
content = "
"
content ="名詞解釋:".decode('UTF-8').encode('GBK')
content = "
"
content ="PSS:實際使用的實體記憶體".decode('UTF-8').encode('GBK')
content = "
"
content ="USS:程序獨自佔用的實體記憶體".decode('UTF-8').encode('GBK')
content = "
"
content = "
"
content ="System效能趨勢:".decode('UTF-8').encode('GBK')
content ="" system_maxminavg.decode('UTF-8').encode('GBK') ""
content = "
"
for i in system_file_list:
pic_name = i.split(sep)[-1]
content = ""
content = "
"
content = "
"
for i in range(0,len(appInfo_list)):
content = "
"
content ="AppInfo:" appInfo_list[i].decode('UTF-8').encode('GBK') ""
content = "
"
for j in app_file_list[i]:
pic_name = j.split(sep)[-1]
content = ""
content = "
"
content = "
"
content =""
content =""
msg.attach(MIMEText(content,_subtype='html',_charset='gb2312'))
for i in system_file_list:
file_name = i.split(sep)[-1]
fp = open(i,'rb')
img = MIMEImage(fp.read())
img.add_header('Content-ID',file_name)
msg.attach(img)
for i in app_file_list:
for j in i:
file_name = j.split(sep)[-1]
fp = open(j,'rb')
img = MIMEImage(fp.read())
img.add_header('Content-ID',file_name)
msg.attach(img)
try:
ott_mail=smtplib.SMTP()
ott_mail.connect(mailserver)
ott_mail.login(user, password)
ott_mail.sendmail(me,mailto_list,msg.as_string())
ott_mail.close()
return True
except Exception,e:
print e
return False
#同步獲取cpu執行緒
#path:寫cpu資訊的檔案路徑
#count:獲取次數
#updateTime:重新整理次數
class CpuThread(threading.Thread):
def __init__(self,path,count,updateTime):
threading.Thread.__init__(self)
self.thread_stop = False
self.path = path
self.count = count
self.updateTime = int(updateTime)
def run(self):
if not self.thread_stop:
print "Cpu thread is start"
self.output = open(self.path, 'w ')
for i in range(self.count):
print "Cpu thread run count:" str(i) " " time.strftime('%Y-%m-%d %X', time.localtime( time.time())) "/n"
self.output.write(run_cmd("adb shell top -n 1 -d " str(self.updateTime)) "/n")
#time.sleep(self.updateTime)
self.output.close()
print "Cpu thread is stop"
def stop(self):
self.thread_stop = True
#同步獲取mem執行緒
#path:寫mem資訊的檔案路徑
#count:獲取次數
#updateTime:重新整理次數
class MemThread(threading.Thread):
def __init__(self,path,count,updateTime):
threading.Thread.__init__(self)
self.thread_stop = False
self.path = path
self.count = count
self.updateTime = int(updateTime)
def run(self):
if not self.thread_stop:
print "Mem thread is start"
self.output = open(self.path, 'w ')
for i in range(self.count):
print "Mem thread run count:" str(i) " " time.strftime('%Y-%m-%d %X', time.localtime( time.time())) "/n"
self.output.write(run_cmd("adb shell procrank") "/n")
time.sleep(self.updateTime)
self.output.close()
print "Mem thread is stop"
def stop(self):
self.thread_stop = True
def analyse_log_and_sendmail(path,sep,startTime,endTime,getCount,updateTime,model,androidVersion,cpuInfo,buildVersionIncremental,buildDate,runTime,packageNameList,mailserver,user,password,me,mailto_list):
system_file_list = []
system_cpu_png = path sep "system_cpu.png"
system_mem_png = path sep "system_mem.png"
system_cpu = analysisSystemCPU(cpu_log_path)
x_list = []
x_list.append(startTime)
for i in range(0,len(system_cpu[0]) - 2):
x_list.append("")
x_list.append(endTime)
get_chart("System_CPU Trend",x_list,"The numerical",[system_cpu[0],system_cpu[1]],system_cpu_png,['User cpu(%)','System cpu(%)'],"{value|0}%")
system_mem = analysisSystemMEM(mem_log_path)
x_list = []
x_list.append(startTime)
for i in range(0,len(system_mem) - 2):
x_list.append("")
x_list.append(endTime)
get_chart("System_MEM Trend",x_list,"The numerical",[system_mem],system_mem_png,['mem(M)'],"{value|2}")
system_maxminavg = "
User CPU(%):max=" str(max(system_cpu[0])) ",min=" str(min(system_cpu[0])) ",avg=" str(round(sum(system_cpu[0])/len(system_cpu[0]),2))/
"
System CPU(%):max=" str(max(system_cpu[1])) ",min=" str(min(system_cpu[1])) ",avg=" str(round(sum(system_cpu[1])/len(system_cpu[1]),2))/
"
MEM(M):max=" str(max(system_mem)) ",min=" str(min(system_mem)) ",avg=" str(round(sum(system_mem)/len(system_mem),2));
system_file_list.append(system_cpu_png)
system_file_list.append(system_mem_png)
bodyinfo = [startTime,endTime,getCount,updateTime,model,androidVersion,cpuInfo,buildVersionIncremental,str(buildDate),runTime]
appInfo_list = []
cpumemChatFile_list = []
#分析日誌
for packageName in packageNameList:
cpu_png = path sep packageName "_cpu.png"
mem_png = path sep packageName "_mem.png"
cpu_list = analysisAppCPU(cpu_log_path,packageName)
if len(cpu_list) == 0:
continue
x_list = []
x_list.append(startTime)
for i in range(0,len(cpu_list) - 2):
x_list.append("")
x_list.append(endTime)
get_chart(packageName "_CPU Trend",x_list,"The numerical",[cpu_list],cpu_png,['cpu(%)'],"{value|0}%")
mem_list = analysisAppMEM(mem_log_path,packageName)
x_list = []
x_list.append(startTime)
for i in range(0,len(mem_list) - 2):
x_list.append("")
x_list.append(endTime)
get_chart(packageName "_PSS_USS Trend",x_list,"The numerical",[mem_list[2],mem_list[3]],mem_png,['pss(M)','uss(M)'],"{value|2}")
appInfo_list.append(packageName "
CPU(%):max=" str(max(cpu_list)) ",min=" str(min(cpu_list)) ",avg=" str(round(sum(cpu_list)/len(cpu_list),2))/
"
PSS(M):max=" str(max(mem_list[2])) ",min=" str(min(mem_list[2])) ",avg=" str(round(sum(mem_list[2])/len(mem_list[2]),2))/
"
USS(M):max=" str(max(mem_list[3])) ",min=" str(min(mem_list[3])) ",avg=" str(round(sum(mem_list[3])/len(mem_list[3]),2)))
cpumemChatFile_list.append([cpu_png,mem_png])
#print appInfo_list
#print cpumemChatFile_list
print "send mail!!!"
print send_mail_image(mailserver,user,password,me,mailto_list,model "-System效能測試報告-" startTime,bodyinfo,system_file_list,system_maxminavg,appInfo_list,cpumemChatFile_list)
if __name__=='__main__':
sep = os.path.sep #獲取系統分隔符
path = sys.path[0] #獲取指令碼路徑
conf_path = path sep "systemMonitor.conf" #監控配置檔案
cpu_log_path = path sep "monitor_cpu.txt" #cpu日誌檔案
mem_log_path = path sep "monitor_mem.txt" #mem日誌檔案
#讀取配置檔案
cf = ConfigParser.ConfigParser()
cf.read(conf_path)
runTime = cf.get("runTime","rumTime")
updateTime = cf.get("updateTime","updateTime")
packageNameList = cf.get("packageNameList","packageNameList").split(",")
mailserver = cf.get("mailInfo","mailserver")
user = cf.get("mailInfo","user")
password = cf.get("mailInfo","password")
me = cf.get("mailInfo","me")
mailto_list = cf.get("mailto_list","mailto_list").split(',')
#檢查配置檔案是否存在
if not os.path.exists(conf_path):
print "systemMonitor.conf is null"
sys.exit()
#生成cpu日誌檔案,如果存在,則先刪除
if os.path.exists(cpu_log_path):
os.remove(cpu_log_path)
#生成mem日誌檔案,如果存在,則先刪除
if os.path.exists(mem_log_path):
os.remove(mem_log_path)
#刪除當前目錄下的.png檔案
for parent,dirnames,filenames in os.walk(path):
for filename in filenames:
if filename[-4:] == ".png":
os.remove(os.path.join(parent,filename))
#檢查環境配置
if runTime == "" or runTime == 0:
print "runTime is null"
sys.exit()
if updateTime == "" or updateTime == 0:
print "updateTime is null"
sys.exit()
if packageNameList == "":
print "packageNameList is null"
sys.exit()
#獲取裝置資訊
model = get_model()
androidVersion = get_androidVersion()
cpuInfo = get_cpuInfo()
buildVersionIncremental = get_buildVersionIncremental()
buildDate = timestamp_datetime(float(get_buildDate()))
#計算top命令-n引數的值,即重新整理多少次
getCount = int(runTime) * 60/int(updateTime)
print "runTime:" runTime
print "updateTime:" updateTime
print "count:" str(getCount)
startTime = getTime()
print "startTime:" startTime
threads = []
#開始執行獲取cpu執行緒
t1 = CpuThread(cpu_log_path,getCount,updateTime)
#開始執行獲取mem執行緒
t2 = MemThread(mem_log_path,getCount,updateTime)
threads.append(t2)
threads.append(t1)
#開始執行所有執行緒
for t in threads:
t.start()
#等待所有執行緒結束
for t in threads:
t.join()
endTime = getTime()
print "endTime:" endTime
analyse_log_and_sendmail(path,sep,startTime,endTime,getCount,updateTime,model,androidVersion,cpuInfo,buildVersionIncremental,str(buildDate),runTime,packageNameList,mailserver,user,password,me,mailto_list)
3.3 analysisInfo.py
#encoding:utf-8
import subprocess
import threading
import time
#分析系統CPU
def analysisSystemCPU(filePath):
fp = open(filePath)
try:
lines = fp.readlines()
finally:
fp.close()
cpu_user_list = []
cpu_system_list = []
for line in lines:
if "User" in line and "System" in line and "IOW" in line and "IRQ" in line:
line_split = line.strip().rstrip('/r').lstrip().split(' ')
cpu_user_list.append(int(line_split[1].replace('%,','')))
cpu_system_list.append(int(line_split[3].replace('%,','')))
return cpu_user_list,cpu_system_list
#分析APP CPU資訊
def analysisAppCPU(filePath,packageName):
fp = open(filePath)
try:
lines = fp.readlines()
finally:
fp.close()
cpu_list = []
for line in lines:
if packageName in line:
line_split = line.strip().rstrip('/r').lstrip().split(' ')
for j in line_split:
if "%" in j:
cpu_list.append(int(j.replace('%','')))
return cpu_list
#分析系統MEM資訊
def analysisSystemMEM(filePath):
fp = open(filePath)
try:
lines = fp.readlines()
finally:
fp.close()
mem_system_list = []
for line in lines:
if "total" in line and "free" in line and "buffers" in line and "cached" in line:
line_split = line.strip().rstrip('/r').lstrip().split(' ')
system_mem = int(line_split[1].replace('K','')) - int(line_split[3].replace('K',''))
mem_system_list.append(round(system_mem/float(1024),2))
return mem_system_list
#分析APP MEM資訊
def analysisAppMEM(filePath,packageName):
fp = open(filePath)
try:
lines = fp.readlines()
finally:
fp.close()
vss_list = []
rss_list = []
pss_list = []
uss_list = []
result_list = []
count = 0
for line in lines:
if packageName in line:
line_split = line.strip().rstrip('/r').lstrip().split(' ')
temp_list = []
for j in line_split:
if "K" in j:
temp_list.append(j.replace('K',''))
count = 1
result_list.append(temp_list)
if count % 4 == 0:
for i in result_list:
vss_list.append(round(float(i[0])/float(1024),2))
rss_list.append(round(float(i[1])/float(1024),2))
pss_list.append(round(float(i[2])/float(1024),2))
uss_list.append(round(float(i[3])/float(1024),2))
return vss_list,rss_list,pss_list,uss_list
else:
return vss_list,rss_list,pss_list,uss_list
def analysisInfo_bak(filePath,packageName):
fp = open(filePath)
lines = fp.readlines()
fp.close()
cpu_list = []
vss_list = []
rss_list = []
cpu_col = 0
vss_col = 0
rss_col = 0
for line in lines:
if packageName in line:
line_split = line.strip().rstrip('/r').lstrip().split(' ')
for j in line_split:
if "%" in j:
cpu_col = line_split.index(j)
if "K" in j:
vss_col = line_split.index(j)
break
for j in line_split[vss_col 1:]:
if "K" in j:
rss_col = line_split.index(j)
break
break
for line in lines:
if packageName in line:
line_split = line.strip().rstrip('/r').lstrip().split(' ')
cpu_list.append(line_split[cpu_col].replace('%',''))
vss_list.append(int(line_split[vss_col].replace('K',''))/float(1024))
rss_list.append(line_split[rss_col].replace('K',''))
return cpu_list,vss_list,rss_list
def run_cmd(cmd):
process = subprocess.Popen(cmd , shell = True, stdout=subprocess.PIPE)
return process.stdout.read().strip()
if __name__=='__main__':
#print analysisSystemMEM("D:/monitor_mem.txt")
#print analysisSystemCPU("D:/monitor_cpu.txt")
#print analysisAppCPU("D:/monitor_cpu.txt","com.bestv.ott")
#print analysisAppMEM("D:/monitor_mem.txt","com.bestv.ott")
pass