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