9. psutil 检测系统各项指标信息
- psutil是一个跨平台库,能够轻松实现获取系统的运行进程和系统利用率(如:cpu,内存,磁盘,网络等)信息,它主要用于系统监控,分析和限制系统资源及进程的管理。
- psutil默认以字节显示(整型int),直接除以3个1024可转换为GB
9.1 获取系统性能信息
cpu
- psutil.cpu_times()完整信息解释说明:
字段名称 |
含义 |
说明 |
user |
用户态 CPU 时间 |
CPU 在用户态下运行普通用户程序所占用的时间。 |
nice |
低优先级用户态 CPU 时间 |
CPU 在用户态下运行低优先级进程(通过 nice 命令调整优先级的进程)所占用的时间。 |
system |
内核态 CPU 时间 |
CPU 在内核态下运行内核代码(如设备驱动程序、文件系统操作等)所占用的时间。 |
idle |
空闲 CPU 时间 |
CPU 处于空闲状态的时间,即 CPU 没有执行任何任务的时间。 |
iowait |
I/O 等待时间 |
CPU 等待 I/O 操作完成的时间(如磁盘读写操作)。 |
irq |
硬件中断时间 |
CPU 处理硬件中断(如键盘、鼠标、网卡等外部设备触发的中断)所占用的时间。 |
softirq |
软件中断时间 |
CPU 处理软件中断(如网络协议栈处理、定时器中断等)所占用的时间。 |
steal |
被虚拟机偷走的时间 |
在虚拟化环境中,CPU 时间被宿主机或其他虚拟机占用的时间。在物理机上通常为 0.0 。 |
guest |
运行虚拟机的时间 |
CPU 在运行虚拟机(如 KVM、Xen 等)时所占用的时间。在物理机上通常为 0.0 。 |
guest_nice |
运行低优先级虚拟机的时间 |
CPU 在运行低优先级虚拟机时所占用的时间。在物理机上通常为 0.0 。 |
#CPU信息
In [3]: import psutil
In [4]: cpu = psutil.cpu_times()
print(cpu)
In [5]: print(cpu)
scputimes(user=46999.48, nice=569.85, system=21047.34, idle=12173417.49, iowait=729.86, irq=0.0, softirq=89.96, steal=0.0, guest=0.0, guest_nice=0.0)
In [6]: print(f"user:{cpu.user},system:{cpu.system},idle:{cpu.idle}")
user:46999.48,system:21047.34,idle:12173417.49
In [7]:
- psutil.cpu_percent(interval=None)返回当前系统范围的cpu使用率(百分比)
In [4]: psutil.cpu_percent(interval=1) #interval默认为None返回系统上一次执行psutil.cpu_percent()函数以来这段时间的cpu使用率,interval=1则返回指定间隔的cpu使用率
Out[4]: 0.0
- psutil.cpu_times_percent() 返回系统cpu时间的百分比
In [5]: psutil.cpu_times_percent()
Out[5]: scputimes(user=0.5, nice=0.0, system=0.2, idle=99.4, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
- psutil.cpu_count()返回cpu的总数
In [6]: psutil.cpu_count()
Out[6]: 2
内存
#内存信息
In [1]: import psutil
In [2]: mem = psutil.virtual_memory() #使用virtual_memory()获取内存的完整信息
In [3]: print(mem)
In [4]: print(f"total:{mem.total},used:{mem.used}")
total:1754292224,used:333479936
In [5]: mem_swap = psutil.swap_memory() #使用swap_memory()获取系统swap交换分区完整信息
In [6]: print(f"swap:{mem_swap}")
swap:sswap(total=0, used=0, free=0, percent=0.0, sin=0, sout=0)
磁盘
#磁盘信息(重点关注磁盘利用率和io读写数)
disk = psutil.disk_partitions() #disk_partitions()获取磁盘的完整信息
print(disk)
disk_usage = psutil.disk_usage('/') #disk_usage('/')指定分区使用情况利用率
print(disk_usage)
disk_io = psutil.disk_io_counters() #disk_io_counters()获取磁盘的总io数
print(disk_io)
disk_io_one = psutil.disk_io_counters(perdisk=True) #disk_io_counters(perdisk=True)获取单个磁盘的io数
print(disk_io_one)
网络
- 网络信息重点关注: bytes_sent=579758412(发送字节数),bytes_recv=1744587596(接收字节数), packets_sent=3704487(发送数据包数),packets_recv=5320867(接收数据包数)
#网络信息
net = psutil.net_io_counters(pernic=True) #net_io_counters()输出总的网络io信息,pernic=True输出每个网络接口的io信息
print(net)
其他信息
In [39]: psutil.users()
Out[39]: [suser(name='root', terminal='pts/2', host='111.26.86.20', started=1738993613.0, pid=191667)]
In [40]: import psutil,datetime
In [41]: psutil.boot_time() #返回时间戳
Out[41]: 1733188166.0
In [42]: datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
Out[42]: '2024-12-03 09:09:26'
案例: 给出进程名输出该进程信息
#!/usr/bin/python3
#_*_coding:utf-8_*_
import psutil
import sys
def print_proc_name(proc_names):
#psutil.pids()默认返回为列表
pids_list = psutil.pids()
try:
for pid in pids_list:
for proc_name in proc_names:
p = psutil.Process(pid)
if p.name() == proc_name:
print(p)
except Exception as e:
print(str(e))
if __name__ == '__main__':
print_proc_name(sys.argv[1:]) #获取用户指定的参数
9.2 系统进程管理
- psutil.process_iter()返回一个包含进程对象的迭代器
In [9]: for proc in psutil.process_iter(['name','pid','username']):
...: print(proc.info)
...:
{'username': 'root', 'pid': 1, 'name': 'systemd'}
{'username': 'root', 'pid': 2, 'name': 'kthreadd'}
{'username': 'root', 'pid': 3, 'name': 'rcu_gp'}
{'username': 'root', 'pid': 4, 'name': 'rcu_par_gp'}
......
- psutil.pids()返回当前运行的pid的有序列表
In [12]: psutil.pids()
Out[12]:
[1,
2,
3,
4,
5,
......]
- psutil.pid_exists(PID)检查指定PID是否存在于当前进程列表中
In [13]: psutil.pid_exists(1)
Out[13]: True
9.3 psutil.Process()类
- psutil.Process(pid=Node) Process类是psutil对进程的封装,可以基于指定pid创建Process对象
In [1]: import psutil
In [3]: psutil.Process(178951) #实例化一个进程对象,参数为进程pid,返回该进程的信息
Out[3]: psutil.Process(pid=178951, name='nginx', status='sleeping', started='2025-02-05 16:02:15')
In [4]: p = psutil.Process(178951)
In [5]: p.name() #进程名
Out[5]: 'nginx'
In [6]: p.exe() #进程bin路径
Out[6]: '/usr/sbin/nginx'
In [7]: p.cwd() #进程的工作目录
Out[7]: '/'
In [8]: p.status() #进程状态
Out[8]: 'sleeping'
In [9]: p.create_time() #进程创建时间
Out[9]: 1738742535.53
In [10]: p.uids()
Out[10]: puids(real=0, effective=0, saved=0)
In [11]: p.gids()
Out[11]: pgids(real=0, effective=0, saved=0)
In [12]: p.cpu_times() #进程的cpu时间,包括user,system
Out[12]: pcputimes(user=0.0, system=0.0, children_user=0.0, children_system=0.0, iowait=0.0)
In [13]: p.cpu_affinity() #进程的cpu亲和度
Out[13]: [0, 1]
In [14]: p.memory_percent() #进程内存利用率
Out[14]: 0.09876393318608247
In [15]: p.memory_info() #进程内存的rss,vms信息(进程的物理内存和逻辑内存)
Out[15]: pmem(rss=1732608, vms=56537088, shared=20480, text=786432, lib=0, data=1482752, dirty=0)
In [16]: p.io_counters() #进程的读写情况
Out[16]: pio(read_count=0, write_count=0, read_bytes=0, write_bytes=0, read_chars=0, write_chars=0)
In [17]: p.connections() #返回打开进程的socket列表
<ipython-input-17-d50301053d22>:1: DeprecationWarning: connections() is deprecated and will be removed; use net_connections() instead
p.connections()
Out[17]:
[pconn(fd=6, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=80), raddr=(), status='LISTEN'),
pconn(fd=7, family=<AddressFamily.AF_INET6: 10>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='::', port=80), raddr=(), status='LISTEN')]
In [18]: p.num_threads() #进程打开的线程数
Out[18]: 1
9.4 psutil.Popen()类
- psutil提供的popen类的作用是获取用户启动的应用程序进程信息,以便跟踪程序进程的运行状态。
#!/usr/bin/python3
#_*_coding:utf-8_*_
import psutil
from subprocess import PIPE
#通过psutil的Popen方法启动应用的程序,可以跟踪该程序运行的所有相关信息
p = psutil.Popen(['/usr/bin/python3','-c','print("hello python")'],stdout=PIPE)
print(p.name())
print(p.username())
print(p.cpu_times())
print(p.communicate())
9.5 psutil实例(监控系统信息)
#!/usr/bin/python3
#_*_coding:utf-8_*_
import psutil
import socket
#通用的字节转换函数
def byte2human(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 f'{value:.1f}{s}'
return f'{n}B'
#检查系统cpu信息
def get_cpu_usage():
cpu_count = psutil.cpu_count() #cpu总数
cpu_precent = psutil.cpu_times_percent(interval=2) #cpu使用率
return dict(cpu_count=cpu_count,cpu_precent=cpu_precent)
#检查内存信息
def get_mem_usage():
mem = psutil.virtual_memory()
mem_total = byte2human(mem.total)
mem_used = byte2human(mem.used)
mem_free = byte2human(mem.free)
return dict(mem_total=mem_total,mem_used=mem_used,mem_free=mem_free)
#检查磁盘信息
def get_disk_usage():
disk = psutil.disk_usage('/')
disk_total = byte2human(disk.total)
disk_used = byte2human(disk.used)
disk_free = byte2human(disk.free)
disk_precent = disk.percent
disk_io = psutil.disk_io_counters()
disk_io_read = byte2human(disk_io.read_bytes)
disk_io_write = byte2human(disk_io.write_bytes)
return dict(disk_total=disk_total,disk_used=disk_used,disk_free=disk_free,disk_precent=disk_precent,
disk_io_read=disk_io_read,disk_io_write=disk_io_write)
#检查网络收发情况
def get_net_data():
net_io = psutil.net_io_counters()
net_io_sent = byte2human(net_io.bytes_sent)
net_io_recv = byte2human(net_io.bytes_recv)
return dict(net_io_sent=net_io_sent,net_io_recv=net_io_recv)
#汇集系统信息
def gather_monitor_data():
data = {}
data.update(get_cpu_usage())
data.update(get_mem_usage())
data.update(get_disk_usage())
data.update(get_net_data())
return data
#报告结果
def report():
#获取主机名
hostname = socket.gethostname()
data = gather_monitor_data()
data.update(dict(hostname=hostname))
#输出系统信息
print(f'{hostname}主机系统信息')
print("------------------------")
print(f'cpu总数: {data["cpu_count"]}')
print(f'cpu使用率: {data["cpu_precent"]}%')
print("------------------------")
print(f'内存总量: {data["mem_total"]}')
print(f'内存使用量: {data["mem_used"]}')
print(f'内存剩余量: {data["mem_free"]}')
print("------------------------")
print(f'磁盘总量: {data["disk_total"]}')
print(f'磁盘使用量: {data["disk_used"]}')
print(f'磁盘剩余量: {data["disk_free"]}')
print(f'磁盘使用率: {data["disk_precent"]}%')
print(f'磁盘读取数据量: {data["disk_io_read"]}')
print(f'磁盘写入数据量: {data["disk_io_write"]}')
print("------------------------")
print(f'网卡发送数据量: {data["net_io_sent"]}')
print(f'网卡接收数据量: {data["net_io_recv"]}')
if __name__ == '__main__':
report()