Linux下有許多使用Python語言編寫的監控工具,如inotify-sync, dstat和glances. 此外,若是要根據業務編寫簡單的監控腳本,不少工程師也會選擇Python語言。Python語言是一門簡單 易學/語法清晰/表達能力強的編程語言,很是適合於編寫監控程序的場景。使用Python語言編寫監控程序具備如下幾個優點:html
咱們將介紹兩個Python語言編寫的監控工具,分別是dstat和glances。node
dstat是一個用Python語言實現的多功能系統資源統計工具,用來取代Linux下的vmstat、iostat、netstat和ifstat等命令。而且,dstat克服了這些命令的限制,增長了額外的功能、以及更多的計數器與更好的靈活性。dstat能夠在一個界面上展現很是全面的監控信息,所以,在系統監控、基準測試和故障排除等應用場景下特別有用。python
咱們可使用dstat監控全部系統資源的使用狀況,而且能夠結合不一樣的場景定製監控的資源。例如,在同一時間段以相同的時間頻率比較網絡帶寬與磁盤的吞吐率。ios
dstat將以列表的形式顯示監控信息,而且用不一樣的顏色進行輸出,以可讀性較強的單位展現監控數值。例如,對於字節數值,dstat自動根據數值的大小,以K、M、G等單位進行顯示,避免了開發者使用其餘命令時由於數值太大形成的困惑和錯誤。此外,使用dstat還能夠很是方便地編寫插件用來收集默認狀況下沒有收集的監控信息。dstat是專門爲人們實時查看監控信息設計的,所以,默認將監控結果輸出到屏幕終端。咱們也能夠將監控信息以CSV格式輸出到文件,以便後續處理。git
做爲一個多功能系統資源統計工具, dstat具備如下特性:web
若是操做系統默認沒有安裝dstat.那麼須要咱們手動進行安裝。以下所示:shell
[root@python ~]# yum -y install dstat
<1>dstat命令的--version選項,除了顯示出tat的版本之外,還會顯示操做系統的版本、Python語言的版本、cpu的個數,以及dstat支持的插件列表等詳細信息。以下所示:編程
[root@python ~]# dstat --version
<2>dstat --list獲取dstat的插件列表vim
dstat --list
<3>直接在終端輸入dstat命令,dstat將以默認參數運行。默認狀況下,dstat會收集cpu、磁盤、網絡、換頁和系統信息,並以一秒鐘一次的頻率進行輸出,直到咱們按 ctrl+c 結束。windows
[root@python ~]# dstat
直接跟數字,表示#秒收集一次數據,默認爲1秒; dstat 5表示5秒更新一次
-c,--cpu 統計CPU狀態,包括system, user, idle, wait, hardware interrupt, software interrupt等; -d, --disk 統計磁盤讀寫狀態 -D total,sda 統計指定磁盤或彙總信息 -l, --load 統計系統負載狀況,包括1分鐘、5分鐘、15分鐘平均值 -m, --mem 統計系統物理內存使用狀況,包括used, buffers, cache, free -s, --swap 統計swap已使用和剩餘量 -n, --net 統計網絡使用狀況,包括接收和發送數據 -N eth1,total 統計eth1接口彙總流量 -r, --io 統計I/O請求,包括讀寫請求 -p, --proc 統計進程信息,包括runnable、uninterruptible、new -y, --sys 統計系統信息,包括中斷、上下文切換 -t 顯示統計時時間,對分析歷史數據很是有用 --fs 統計文件打開數和inodes數
除了前面介紹的與監控相關的參數之外,dstat還能夠像vmstat和iostat- 樣使用參數控制報告的時間間隔,或者同時指定時間間隔與報告次數。
例如,下面的命令表示以默認的選項運行dstat,每2秒鐘輸出1條監控信息,並在輸出10條監控信息之後退出dstat。以下所示:
[root@python ~]# dstat 2 10 You did not select any stats, using -cdngy by default. Terminal width too small, trimming output. ----total-cpu-usage---- -dsk/total- -net/total- ---paging--> usr sys idl wai hiq siq| read writ| recv send| in out > 2 1 96 0 0 0| 270k 233k| 0 0 | 75B 1812B> 0 0 100 0 0 0| 0 0 | 60B 510B| 0 0 > 0 0 100 0 0 0| 0 0 | 60B 294B| 0 0 > 0 1 100 0 0 0| 0 0 | 60B 294B| 0 0 > 0 0 100 0 0 0| 0 0 | 182B 294B| 0 0 > 1 0 100 0 0 0| 0 0 | 60B 294B| 0 0 > 0 1 99 0 0 0| 0 0 | 60B 294B| 0 0 > 0 1 100 0 0 0| 0 0 | 60B 294B| 0 0 > 0 0 100 0 0 0| 0 0 | 60B 294B| 0 0 > 1 0 100 0 0 0| 0 0 | 60B 294B| 0 0 > 0 0 100 0 0 0| 0 25k| 60B 298B| 0 0 >
dstat命令中有不少參數可選,你能夠經過man dstat命令查看,大多數經常使用的參數有這些:
dstat附帶了一些插件很大程度地擴展了它的功能。你能夠經過查看/usr/share/dstat目錄來查看它們的一些使用方法,經常使用的有這些:
-–top-cpu
:圖形化顯示CPU佔用最大的進程dstat的強大之處不只僅是由於它聚合了多種工具的監控結果,還由於它能經過附帶的插件事項一些更高級功能。
如:找出磁盤重佔用資源最高的進程和用戶。
dstat -cdlmnpsyt 5 能夠獲得較全面的系統性能數據。
dstat的--top-(io|bio|cpu|cputime|cputime-avg |mem)經過這幾個選項,能夠看到具體是那個用戶哪一個進程佔用了相關係統資源, 對系統調優很是有效。如查看當前佔用I/O、 cpu、內存等最高的進程信息可使用dstat --top-mem --top-io --top-cpu
選項。如下示例演示瞭如何找出佔用資源最多的進程。
[root@python scripts]# dstat --top-mem --top-io --top-cpu //查看當前佔用I/O、CPU、內存等最高的進程信息 --most-expensive- ----most-expensive---- -most-expensive- memory process | i/o process | cpu process gnome-shell 53.0M|bash 420k 119k|vmtoolsd 0.1 gnome-shell 53.0M|BT-Task 1026B 0 | gnome-shell 53.0M|gnome-shell 352B 82k|kworker/0:0 1.0 gnome-shell 53.0M|sshd: root@ 230B 196B| gnome-shell 53.0M|sshd: root@ 155B 196B| gnome-shell 53.0M|sshd: root@ 155B 196B| gnome-shell 53.0M|sshd: root@ 155B 196B| gnome-shell 53.0M|BT-Task 1406B 0 |
dstat的插件保存在/usr/share/dstat目錄下, 咱們能夠參考它們的實現,編寫本身的插件。
dstat還能夠將監控信息保存到CSV文件中,以便後續進行處理。經過--output選項指定監控數據輸出的文件。以下所示:
[root@python ~]# dstat -a --output dstat_output.csv Terminal width too small, trimming output. ----total-cpu-usage---- -dsk/total- -net/total- ---paging--> usr sys idl wai hiq siq| read writ| recv send| in out > 2 1 97 0 0 0| 175k 158k| 0 0 | 59B 1973B> 0 0 100 0 0 0| 0 0 | 150B 822B| 0 0 > 0 0 100 0 0 0| 0 0 | 60B 298B| 0 0 > 0 0 100 0 0 0| 0 0 | 60B 298B| 0 0 > 0 0 100 0 0 0| 0 0 | 60B 298B| 0 0 > 0 1 99 0 0 0| 0 0 | 60B 298B| 0 0 > 0 0 100 0 0 0| 0 0 | 210B 448B| 0 0 > 1 0 99 0 0 0| 0 49k| 60B 298B| 0 0 > 0 0 100 0 0 0| 0 0 | 210B 396B| 0 0 > 0 0 100 0 0 0| 0 0 | 60B 298B| 0 0 >^C
[root@python ~]# sz dstat_output.csv //導出本地文件到windows指定位置
glances是一款使用Python語言開發、基於psutil的跨平臺系統監控工具。在全部的Linux命令行工具中,它與top命令最類似,都是命令行交互式監控工具。可是,glances實現了比top命令更齊全的監控,提供了更加豐富的功能。
在緊急狀況下,工程師須要在儘量短的時間內查看盡量多的信息。此時,glances是一個不錯的選擇。 glances的設計初衷就是在當前窗口中儘量多地顯示系統消息。
glances能夠在用戶終端上實時顯示重要的系統信息,並動態刷新內容。glances每隔3秒鐘對其進行刷新,咱們也可使用命令行參數修改刷新的頻率。與dstat相同的是,glances能夠將捕獲到的數據保存到文件中;而不一樣的是glances提供了API接口以便應用程序從glances中獲取數據。
glances 工具能夠在用戶的終端上實時顯示重要的系統信息,並動態地對其進行更新。這個高效的工具能夠工做於任何終端屏幕。另外它並不會消耗大量的 CPU 資源,一般低於百分之二。glances 在屏幕上對數據進行顯示,而且每隔2秒鐘對其進行更新。您也能夠本身將這個時間間隔更改成更長或更短的數值。
glances 工具還能夠將相同的數據捕獲到一個文件,便於之後對報告進行分析和繪製圖形。輸出文件能夠是電子表格的格式 (.csv) 或者 html 格式。
#須要epel-release yum -y install epel-release yum -y install glances
或
#須要python-devel yum -y install python-devel -y pip install glances
glances的使用很是簡單,直接輸入glances命令便進入了一個相似於top命令的交互式界面。在這個界面中,顯示了比top更加全面,更加具備可讀性的信息。
爲了增長可讀性,glances會以不一樣的顏色表示不一樣的狀態。其中,綠色:性能xingnenglaingh良好,元須作任何額外工做;藍色表示系統性能有一些小問題,用戶應當開始關注系統性能;紫色:性能報警,應當採起措施;紅色:性能問題嚴重,應當當即處理。
lances是一個交互式的工具.所以,咱們也能夠輸入命令來控制glances的行爲。
[root@python ~]# glances
在圖 1 的上部是 CPU 、Load(負載)、Mem(內存使用)、 Swap(交換分區)的使用狀況。在圖 1 的中上部是網絡接口、Processes(進程)的使用狀況。一般包括以下字段:
對比能夠發現,glances對屏幕的利用率比top明顯高不少,信息量很大,有許多top所沒有顯示的數據。並且,glances的實時變更比top顏值高太多了。
Glances 會用一下幾種顏色來表明狀態,以下所示:
glances還支持將採集的數據導入到其餘服務中心,包括InfluxDB、 Cassandra. CouchDB、 OpenTSDB、Prometheus. StatsD、 ElasticSearch, RabbitMQ/ActiveMQ、ZeroMQ、 Kafaka和Riemann.
glances還支持將採集的數據導人到其餘服務中心,包括InfluxDB,Cassandra,CouchDB,OpenTSDB,Prometheus,StatsD,ElasticSearch,RabbitMQ/ActiveMQ,ZeroMQ,Kafka和Riemann。
[root@python ~]# pip install bottle //安裝Bottle框架 [root@python ~]# glances -w ##默認端口是61208,訪問地址沒有限制 Glances Web User Interface started on http://0.0.0.0:61208/
shell查看磁盤的監控信息,以下所示:
[root@python proc]# cat /proc/diskstats 8 0 sda 85935 21845 10913707 101067 3119 81257 743486 15647 0 31410 109079 8 1 sda1 1822 0 12456 397 4 0 4096 74 0 457 462 8 2 sda2 84082 21845 10897907 100659 3115 81257 739390 15573 0 30950 108604 11 0 sr0 0 0 0 0 0 0 0 0 0 0 0 253 0 dm-0 80726 0 10688467 99971 2275 0 82606 10224 0 27927 110196 253 1 dm-1 25123 0 205184 7367 82098 0 656784 616558 0 5167 623924
dos2unix 和 unix2dos 命令將純文本文件從 DOS 或 Mac 格式轉換爲 Unix,反之亦然。
[root@python scripts]# yum -y install dos2unix //下載dos2unix
[root@python scripts]# vim monitor.sh #/bin/sh cpu_idle=$(top -n2 | grep 'Cpu' | tail -n 1 | awk '{print $8}') cpu_usage=$(printf "%.2f" `echo "scale=2; 100 - $cpu_idle" | bc`) mem_free=$(free -m | awk '/Mem:/{print $4 + $6 +$7}') mem_total=$(free -m | awk '/Mem:/{print $2}') mem_used=$(echo "$mem_total - $mem_free" | bc) mem_rate=$(echo "$mem_used * 100 / $mem_total" | bc) disk_usage=$(df -h / | tail -n 1 | awk '{print $5}') disk_used=$(df -h / | tail -n 1 | awk '{print $3}') echo "CPU利用率:$cpu_usage %" echo "內存使用量: $mem_used M" echo "內存利用率:$mem_rate %" echo "磁盤空間使用量:$disk_used" echo "磁盤空間利用率:$disk_usage"
[root@python scripts]# dos2unix monitor.sh //轉換爲格式爲Unix [root@python scripts]# cat monitor.sh #/bin/sh cpu_idle=$(top -n2 | grep 'Cpu' | tail -n 1 | awk '{print $8}') cpu_usage=$(printf "%.2f" `echo "scale=2; 100 - $cpu_idle" | bc`) mem_free=$(free -m | awk '/Mem:/{print $4 + $6 +$7}') mem_total=$(free -m | awk '/Mem:/{print $2}') mem_used=$(echo "$mem_total - $mem_free" | bc) mem_rate=$(echo "$mem_used * 100 / $mem_total" | bc) disk_usage=$(df -h / | tail -n 1 | awk '{print $5}') disk_used=$(df -h / | tail -n 1 | awk '{print $3}') echo "CPU利用率:$cpu_usage %" echo "內存使用量: $mem_used M" echo "內存利用率:$mem_rate %" echo "磁盤空間使用量:$disk_used" echo "磁盤空間利用率:$disk_usage" [root@python scripts]# sh monitor.sh //執行編寫好的腳本
編寫一個Python腳本,監控磁盤信息,以下所示:
[root@python scripts]# vim proc_count.py import os n = 0 for item in os.listdir('/proc'): if item.isdigit(): n = n+1 # print(len(item)) print(n)
[root@python scripts]# python3 proc_count.py 175
[root@python scripts]# vim monitor_dick.py # coding=utf-8 # !/usr/bin/python from __future__ import print_function from collections import namedtuple disk = namedtuple('Disk', 'major_number minor_number device_name' ' read_count read_merged_count read_sections' ' time_spent_reading write_count write_merged_count' ' write_sections time_spent_write io_requests' ' time_spent_doing_io weighted_time_spent_dong_io') def get_disk_info(device): with open('/proc/diskstats') as f: for line in f: if line.split()[2] == device: return disk(*(line.split())) raise RuntimeError('設備({0})沒找到。。。'.format(device)) def main(): disk_info = get_disk_info('sda1') print(disk_info) if __name__ == '__main__': main()
[root@python scripts]# python3 monitor_dick.py
# coding=utf-8 # !/usr/bin/python from __future__ import print_function from collections import namedtuple disk = namedtuple('Disk', 'major_number minor_number device_name' ' read_count read_merged_count read_sections' ' time_spent_reading write_count write_merged_count' ' write_sections time_spent_write io_requests' ' time_spent_doing_io weighted_time_spent_dong_io') def get_disk_info(device): with open('/proc/diskstats') as f: for line in f: if line.split()[2] == device: return disk(*(line.split())) raise RuntimeError('設備({0})沒找到。。。'.format(device)) def main(device): disk_info = get_disk_info(device) print(disk_info) print("磁盤寫入次數:{0}".format(disk_info.write_count)) print("磁盤寫入的字節數:{0}".format(float(disk_info.write_sections) * 512)) print("磁盤寫入的延時:{0}".format(disk_info.time_spent_write)) if __name__ == '__main__': main('sda1')
[root@python scripts]# python3 monitor_dick.py