如果使用過glances
,如果有一顆geek的心的話,一定會覺得不但酷炫而且十分實用。不過如果想觀察一個程序從運行開始到結束的cpu佔用率怎麼辦?好辦,利用python的psutil
異步觀察就行。
介紹一下放在github上的一個項目: oscillo
使用方式
使用方式很簡單,直接 pip install oscillo
即可安裝使用.
命令行參數的格式是 "<name>: <command [args]>"
:
-
name
: 命令行的別名/id (任意字符串),當--commands/-c
參數指定多個命令時,該值將作爲命令的唯一標識,不可重複 -
command [args]
: 需要測試資源消耗的命令,比如gzip file.ext
示例如下,監控gzip壓縮一個文件時耗費的cpu、memory和時間:
oscillo -c 'gzip: gzip file.ext' -o output-file
- -c 代表將執行一個linux cmd 命令。參數後面可以跟以空格隔開的多個參數
- -o 結果輸出文件:
命令執行完成後,會在當前目錄下生成一個<output-file>.log
文件。文本結構是json 格式. 數據結構如下
{
"test": {
"elapsed": 0.022143125534057617, //總執行時間
"cpu": [],
"memory": []
}
}
同時會產生一個<output-file>.png
文件,<output-file>
由-o
參數指定,默認值爲metrix
在控制檯上,oscillo
會打印summary信息,其中包含命令的耗時、最大內存使用、最大cpu使用、退出碼等在控制檯上,oscillo
會打印summary信息,其中包含命令的耗時、最大內存使用、最大cpu使用、退出碼等
如果想對比多個命令對資源的消耗,可以使用 -c/--commands
選項指定多條命令, e.g.:
對比gzip
和tar
命令對資源的消耗:
oscillo -c 't1: gzip file.ext' 't2: tar czf target.tar.gz file1' -o output
效果如下:
實現原理
這個工具的原型,來自於一次爲了對比幾種客戶端性能而寫的一個腳本,它的原理就是:
- 在程序中啓動一個子進程,獲取進程id
- 通過
psutil
觀察該進程,每隔一段時間記錄一次cpu和內存的負載 - 通過
matplotlib
畫圖
說一下其中碰到的一個坑:欲監控的子進程A在內部調用了另一個耗資源的子進程B,但是psutil只能觀察到子進程A的資源消耗情況,粗暴的解決辦法就是:觀察全局的資源消耗情況:
class Stopwatch(object):
def __init__(self, pid):
self.__is_run = False
self.__start_time = 0
self.__elapsed_times = 0
self.memory_percent = []
self.cpu_percent = []
self.pid = pid
def start(self):
if self.__is_run:
return False
self.__is_run = True
self.__start_time = time.time()
if self.pid > 0:
p = psutil.Process(self.pid)
else:
p = psutil
p.memory_percent = lambda: p.virtual_memory().percent
while self.__is_run:
try:
self.cpu_percent.append(p.cpu_percent(1))
self.memory_percent.append(p.memory_percent())
except psutil.NoSuchProcess:
break
@property
def elapsed(self):
if self.__is_run:
return self.__elapsed_times + time.time() - self.__start_time
return self.__elapsed_times
def stop(self):
self.__elapsed_times = self.elapsed
self.__is_run = False
BTW
當前的功能比較簡單,可能有很多東西沒用想到,歡迎使用和完善
git倉庫: oscillo