六 使用psutil开源库监控Linux系统信息
一、psutil介绍
psutil是一个开源且跨平台的库,其提供了便利的函数用来获取操作系统的系统信息,如CPU,内存,磁盘,网络等信息。此外,psutil还可以用来进行进程管理,包括判断进程是否存在,获取进行列表,获取进程的详细信息等。psutil广泛应用于系统监控,进程管理资源限制等场景。此外psutil还提供了许多命令行工具提供的功能,包括ps,top,lsof,netstat,ifconfig,who,df,kill,free,nice,ionice,iostat,iotop,uptime,pidof,tty,taskset,pmap.
psutil是一个跨平台库,支持Linux,Windows,OSX,Sun Solaris,FreeBSD,OpenBSD以及NetBSD等操作系统。同时,psutil也支持32位与64位的系统架构,支持Python2.6到Python3.6之间所有Python版本。psutil具有简单易用,功能强大,跨平台等诸多优点,广泛应用于开源项目中,比较有名的有glances,facebook的osquery,google的grr等。psutil不但广泛应用于Python语言开发的开源项目中,还被移植到了其他编程语言中,如Go语言的gopsutil,C语言的cpslib,Rust语言的rust-psutil,Ruby语言的posixpsutil等,作为一个不算复杂的开源项目,psutil可以说是非常成功了。
二、psutil提供的功能函数
CPU
- CPU_count 默认返回逻辑cpu的个数,也可以指定logical=False获取物理CPU的个数
>>> import psutil
>>> psutil.cpu_count()
4
>>> psutil.cpu_count(logical=False)
2
- cpu_percent返回cpu的利用率,可以通过interval参数阻塞式地获取interval时间范围内的cpu利用率,否则,获取上一次调用cpu_percent这段时间以来的cpu利用率。可以使用percpu参数指定获取每个cpu的利用率,默认获取整体的cpu利用率。
>>> psutil.cpu_percent()
16.2
>>> psutil.cpu_percent(percpu=True)
[26.3, 7.1, 21.9, 7.4]
>>> psutil.cpu_percent(interval=2,percpu=True)
[15.4, 3.5, 13.4, 3.5]
- cpu_times 以命名元组的形式返回CPU的时间花费,也可以通过percpu参数指定获取每个cpu的统计时间
>>> psutil.cpu_times()
scputimes(user=4080.4, nice=0.0, system=2914.83, idle=44246.5)
- cpu_times_percent与cpu_times类似,但是返回的是消耗时间的比例
>>> psutil.cpu_times_percent()
scputimes(user=7.5, nice=0.0, system=8.0, idle=84.5)
- cpu_stats 以命名元组的形式返回cpu的统计信息,包括上下文切换,中断,软中断和系统调用的次数。
>>> psutil.cpu_stats()
scpustats(ctx_switches=51017, interrupts=976877, soft_interrupts=37786204, syscalls=312264)
内存
1)virtual_memory 以命名元组的形势返回内存使用情况,包括总内存,可用内存,内存利用率,buffer和cached等。除了内存利用率,其他字段都以字节为单位返回。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import psutil
print(psutil.virtual_memory())
def bytes2human(n):
symbols = ('k','M','G','T','P','E','Z','Y')
prefix = {}
for i,s in enumerate(symbols):
prefix[s] = 1 << (i+1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%s.1f%s' %(value,s)
return '%sB' %n
data = bytes2human(psutil.virtual_memory().total)
print(data)
# run
/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/psutil(系统性能信息模块)/监控内存.py
svmem(total=8589934592, available=1657434112, percent=80.7, used=7007428608, free=63401984, active=1677914112, inactive=1594032128, wired=3735482368)
8.0.1fG
- swap_memory 以命名元组的形式返回swap memory的使用情况,显然,对swap memory的统计包含了页的换入与换出
>>> psutil.swap_memory()
sswap(total=1073741824, used=15466496, free=1058275328, percent=1.4, sin=4888276992, sout=376942592)
>>>
磁盘
- disk_partitions返回所有已经挂载的磁盘,以命名元组的形式返回。命名元组包含磁盘名称,挂载点,文件系统类型等信息。可以通过disk_partions获取挂在点挂载的磁盘。
>>> import psutil
>>> psutil.disk_partitions()
[sdiskpart(device='/dev/disk1', mountpoint='/', fstype='hfs', opts='rw,local,rootfs,dovolfs,journaled,multilabel')]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import psutil
def get_disk_via_mount_point(mount_point):
disk = [item for item in psutil.disk_partitions()
if item.mountpoint == mount_point]
return disk[0].device
data = get_disk_via_mount_point('/') # 挂载信息
print(data)
# run
/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/psutil(系统性能信息模块)/监控磁盘.py
/dev/disk1
- disk_io_counters 以命名元组的形式返回磁盘io统计信息,包括读的次数,写的次数,读字节数,写字节数等。
import psutil
print(psutil.disk_io_counters())
print(psutil.disk_io_counters(perdisk=True))
# run
/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/psutil(系统性能信息模块)/监控磁盘.py
sdiskio(read_count=258889, write_count=90420, read_bytes=6949387776, write_bytes=3234383872, read_time=104885, write_time=58055)
{'disk0': sdiskio(read_count=258889, write_count=90420, read_bytes=6949387776, write_bytes=3234383872, read_time=104885, write_time=58055)}
网络
1)net.io_counter返回当前系统中网络io统计信息是监控系统中需要关注的网络信息。net_io_counter函数以命名元组的形式返回了每块网卡的网络io统计信息,包括收发字节数,收发包的数量,出错情况与删包情况。使用net_io_counter函数与自己解析/proc/net/dev 文件内容实现的功能相同
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import psutil
print(psutil.net_io_counters())
print(psutil.net_io_counters(pernic=True))
# run
snetio(bytes_sent=34290884, bytes_recv=876352042, packets_sent=458261, packets_recv=694981, errin=0, errout=24, dropin=0, dropout=0)
{'lo0': snetio(bytes_sent=2311824, bytes_recv=2311824, packets_sent=23943, packets_recv=23943, errin=0, errout=0, dropin=0, dropout=0), 'gif0': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'stf0': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'en0': snetio(bytes_sent=725159, bytes_recv=2629392, packets_sent=4894, packets_recv=3932, errin=0, errout=0, dropin=0, dropout=0), 'en1': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'en2': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'en3': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'en4': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'bridge0': snetio(bytes_sent=342, bytes_recv=0, packets_sent=1, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'p2p0': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'awdl0': snetio(bytes_sent=1396, bytes_recv=0, packets_sent=6, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'en5': snetio(bytes_sent=332090, bytes_recv=472321, packets_sent=1717, packets_recv=1824, errin=0, errout=0, dropin=0, dropout=0), 'utun0': snetio(bytes_sent=268, bytes_recv=0, packets_sent=3, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'en7': snetio(bytes_sent=30919805, bytes_recv=870415610, packets_sent=427697, packets_recv=660412, errin=0, errout=24, dropin=0, dropout=0), 'vnic0': snetio(bytes_sent=0, bytes_recv=520879, packets_sent=0, packets_recv=4849, errin=0, errout=0, dropin=0, dropout=0), 'vnic1': snetio(bytes_sent=0, bytes_recv=2016, packets_sent=0, packets_recv=21, errin=0, errout=0, dropin=0, dropout=0)}
- net_if_addrs 以字段的形式返回网卡的配置信息,包括ip地址或mac地址,子网掩码和广播地址
print(psutil.net_if_addrs())
# run
etmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None)], 'en7': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.12.222', netmask='255.255.255.0', broadcast='192.168.12.255',
- net_if_stats 返回网卡的详细信息,包括是否启动,通信类型,传输速度与mtu。
print(psutil.net_if_stats())