diff --git a/.ignore b/.ignore new file mode 100644 index 0000000..cd419fb --- /dev/null +++ b/.ignore @@ -0,0 +1,91 @@ +#Eclipse +.settings/ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..662779b --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + PythonAndroidMonitor + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/.pydevproject b/.pydevproject new file mode 100644 index 0000000..3d1522a --- /dev/null +++ b/.pydevproject @@ -0,0 +1,8 @@ + + +python 2.7 +Default + +D:\workspace\python-adb\adb + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..57d3ec7 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# PythonAndroidMonitor # + +This tool is used to monitor device memory info base on adb command and python, data is saved to CSV file, and can be used to make Excel chart. + +###Note: + 1. adb should be added in environment path; + 2. python code is based Python3.x; + 3. Excel chart may need adjust depend on data size. + 4. Example chart: + ![](http://i.imgur.com/Jz83hED.png) + +###User guide: + 1. Connect your mobile phone to pc; + 2. Run the script, and input process you will monitor, for example: com.zebra.carcloud.gate; + > Please input the process name: + 3. Input catch interval in seconds, such as 10, too small is meaningless; + > Please input the catch interval(second, value should >= 10): + 4. When the script run for while, the data is saved at: + > %USER%\PythonAndroidMonitor directory + + On windows, it's C:\Users\%user name%\Desktop\PythonAndroidMonitor\%datetime%, the directory name is last run datetime. + 5. Open the folder,mem_history.txt record detail info and mem_abstract.CSV record abstract info. + ![](http://i.imgur.com/42s2CKn.png) +mem_abstract.CSV colums: PID,ProcessName,Datetime,PSS(KB) +![](http://i.imgur.com/Rw1oFqA.png) + 6. Open 内存占用情况.xlsx. + 7. In Sheet1, Click '数据' in tool bar,and then click '全部刷新',and select the CSV file created, wait till data changed, you can find chart in Sheet2. + ![](http://i.imgur.com/6ZAZ38b.png) + Sometime, you can adjust chart style depends on data size. diff --git a/process_mem_info_recorder.py b/process_mem_info_recorder.py new file mode 100644 index 0000000..989ebe8 --- /dev/null +++ b/process_mem_info_recorder.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os, time +import subprocess +import sys +import re +import platform +from time import gmtime, strftime + +class MemInfo: + patternProcess = re.compile(r'\*\* MEMINFO in pid (\d+) \[(\S+)] \*\*') + patternTotalPSS = re.compile(r'TOTAL:\s+(\d+)') + + pid = 0 + processName = '' + datetime = '' + totalPSS = 0 + + def __init__(self, dump): + self.dump = dump + self._parse() + + def _parse(self): + match = self.patternProcess.search(self.dump) + if match: + self.pid = match.group(1) + self.processName = match.group(2) + match = self.patternTotalPSS.search(self.dump) + if match: + self.totalPSS = match.group(1) + +def dumpsys_process_meminfo(process): +# os.system('adb shell dumpsys meminfo "' + process) + proc = subprocess.Popen(args='adb shell dumpsys meminfo "' + process + '"', stdout=subprocess.PIPE, stderr=sys.stderr, shell=True) + out = proc.communicate()[0] + return MemInfo(dump=out.decode(encoding='windows-1252')) + +def re_exe(process, dir, historyFileName, abstractFileName, interval=60): + if not os.path.exists(dir): + os.makedirs(dir) + + with open(dir + "\\" + abstractFileName, "a") as write_abstract_file: + with open(dir + "\\" + historyFileName, "a") as write_history_file: + try: + while True: + datetime = strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) + memInfo = dumpsys_process_meminfo(process) + + if memInfo.dump == '': + break + elif memInfo.dump.startswith('No process found for:') : + raise RuntimeError() + + memInfo.datetime = datetime + write_history_file.write('\n') + write_history_file.write(datetime) + write_history_file.write(memInfo.dump) + write_history_file.flush() + + write_abstract_file.write(str(memInfo.pid) + "," + memInfo.processName + "," + datetime + "," + str(memInfo.totalPSS)) + write_abstract_file.write('\n') + write_abstract_file.flush() + + print(memInfo.dump) +# print('\n\nPress CTRL+C to break loop:') + time.sleep(interval) + except RuntimeError: + print(memInfo.dump) + except KeyboardInterrupt: + pass + +if __name__ == "__main__": + usr = os.path.expanduser('~') + platform = platform.system() + desktop = '' + + if platform == 'Windows': + desktop = r'\Desktop'; + + out_path = usr + desktop + r"\PythonAndroidMonitor" + out_mem_history_file = "mem_history.txt" + out_mem_abstract_file = "mem_abstract.CSV" + dir = strftime("%Y-%m-%d %H-%M-%S", time.localtime(time.time())) + + process = input("Please input the process name:") + interval = 0 + + while not interval: + try: + interval = int(input('Please input the catch interval(second, value should >= 10):')) + if interval < 10: + raise Exception + except ValueError: + interval = 0 + print("Please input integer!") + except Exception: + interval = 0 + print("Value should >= 10!") + + re_exe(process=process, dir=out_path + "\\" + dir, historyFileName=out_mem_history_file, abstractFileName=out_mem_abstract_file, interval=interval) diff --git "a/\345\206\205\345\255\230\345\215\240\347\224\250\346\203\205\345\206\265.xlsx" "b/\345\206\205\345\255\230\345\215\240\347\224\250\346\203\205\345\206\265.xlsx" new file mode 100644 index 0000000..506fbb6 Binary files /dev/null and "b/\345\206\205\345\255\230\345\215\240\347\224\250\346\203\205\345\206\265.xlsx" differ