1.psutil模块详解
psutil是一个跨平台模块,试用相应方法可以直接获取计算机CPU,内存,磁盘,网络等资源使用情况;可以使用我们学习知识与这模块用来做系统监控,性能分析;如果大家熟悉Linux系统,它能够实现ps、top、lsof、netstat、df等命令功能。
1.1psutil安装:
psutil是第三方模块,使用时候需要要安装,相关说明链接地址:
https://pypi.org/project/psutil/ ;
pip安装方式:
pip install psutil
验证:
#导入模块
import psutil
#查看版本信息
psutil.version_info
输出信息:
(5, 4, 8)
这里说明安装成功(版本可能会不同,但是不影响使用);
1.2 获取CPU信息
使用下面这些方法可以获取计算机CPU数量,CPU使用率:
方法 | 说明 |
---|---|
cpu_count(logical=True) | 获取CPU数量 |
cpu_times(percpu=False) | 获取不同状态下CPU运行时间 |
cpu_percent(interval=None, percpu=False) | 获取CPU使用率 |
cpu_times_percent(interval=None, percpu=False) | 获取CPU各状态占百分比 |
两个个知识点需要简单介绍下,这里只需要了解即可:
1)CPU数量:CPU分为物理CPU与逻辑CPU,之间关系如下:
1>物理CPU:计算机实际CPU数量,一般个人电脑1个;
2>核数:现在CPU基本都是多核,比如双核,4核;
3>逻辑CPU:物理CPU*核数*超线程数
2)CPU运行状态分为用户态与内核态;
1>用户态是指程序在内存运行,不直接访问硬件资源;
2>用户需要访问硬件资源,需要系统调用,这部分有操作系统(内核)完成,称为内核态,例如:读写文件,网络数据收发,键盘事件获取等;
下面我们来实际操作下(windows环境):
import psutil
#获取CPU不同状态运行时间
print(psutil.cpu_times())
print('CPU 执行用户进程时间:', psutil.cpu_times().user)
print('CPU 执行系统调用时间:', psutil.cpu_times().system)
print('CPU 空闲等待 时间:', psutil.cpu_times().idle)
print('CPU 响应中断 时间:', psutil.cpu_times().interrupt)
#CPU使用率:不加参数为上一次调用到现在使用率
print('CPU 使用率:',psutil.cpu_percent())
#3秒内CPU使用率
print('CPU 3秒内使用率:',psutil.cpu_percent(interval=3))
#3秒内每个CPU使用率
print('每个逻辑CPU使用率:',psutil.cpu_percent( percpu = True))
#CPU各个状态使用情况(百分比)
print('CPU 各个状态使用情况:',psutil.cpu_times_percent())
#每个CPU各个状态使用情况
print('各个CPU 各个状态使用情况:')
cpuinfos = psutil.cpu_times_percent(percpu = True)
for info in cpuinfos:
print(info)
运行结果如下:
scputimes(user=85326.484375, system=56630.8125, idle=2245745.0625, interrupt=5347.296875, dpc=1395.984375)
CPU 执行用户进程时间: 85326.484375
CPU 执行系统调用时间: 56630.8125
CPU 空闲等待 时间: 2245745.0625
CPU 响应中断 时间: 5347.296875
CPU 使用率: 3.4
CPU 3秒内使用率: 2.5
每个逻辑CPU使用率: [7.0, 2.1, 4.5, 2.5, 2.7, 2.1, 2.1, 2.7]
CPU 各个状态使用情况: scputimes(user=1.4, system=1.5, idle=96.8, interrupt=0.3, dpc=0.0)
各个CPU 各个状态使用情况:
scputimes(user=1.8, system=3.1, idle=93.0, interrupt=1.9, dpc=0.2)
scputimes(user=0.4, system=1.6, idle=97.9, interrupt=0.1, dpc=0.0)
scputimes(user=1.6, system=2.8, idle=95.5, interrupt=0.1, dpc=0.0)
scputimes(user=1.0, system=1.4, idle=97.5, interrupt=0.1, dpc=0.0)
scputimes(user=2.4, system=0.2, idle=97.3, interrupt=0.0, dpc=0.0)
scputimes(user=1.1, system=1.0, idle=97.9, interrupt=0.0, dpc=0.0)
scputimes(user=0.8, system=1.2, idle=97.9, interrupt=0.0, dpc=0.0)
scputimes(user=1.8, system=0.7, idle=97.3, interrupt=0.1, dpc=0.0)
对于不同系统,获取内容稍微有所不同,大家可以在linux尝试下操作。
1.3 获取系统内存信息
程序在内存中运行,实际工作中我们需要对内存进行监控,如果内存使用接近100%,可能存在内存泄漏等问题;我们主要关注内存的total(内存总数),used(已使用),free(未使用)情况,相关方法如下:
方法 | 说明 |
---|---|
psutil.virtual_memory | 获取内存使用情况,不同系统返回值不同 |
psutil.swap_memory() | 获取swap内存使用情况 |
实际操作如下(windows环境下):
import psutil
mem = psutil.virtual_memory()
print('系统内存:', mem)
print('总 内存:', mem.total)
print('空闲内存:', mem.available)
print('使用内存:', mem.used)
print('未使用内存:', mem.free)
print('内存使用率:', mem.percent)
print('swap 内存:', psutil.swap_memory())
输出结果:
系统内存: svmem(total=8494747648, available=5058498560, percent=40.5, used=3436249088, free=5058498560)
总 内存: 8494747648
空闲内存: 5058498560
使用内存: 3436249088
未使用内存: 5058498560
内存使用率: 40.5
swap 内存: sswap(total=15205634048, used=4902215680, free=10303418368, percent=32.2, sin=0, sout=0)
看到这些数字有点晕,我们更喜欢M或者G来堆内存进行描述,修改下代码:
import psutil
#1M = 1024*1024
#1G = 1024*1024*1024
M = 1024*1024
G = M * 1024
mem = psutil.virtual_memory()
print('系统内存:', mem)
print('总 内存:%dM %fG'%(mem.total//M, mem.total/G))
print('空闲内存:%dM %fG'%(mem.available//M, mem.available/G))
print('使用内存:%dM %fG'%(mem.used//M, mem.used/G))
print('未使用内存:%dM %fG'%(mem.free//M, mem.free/G))
print('内存使用率:%d%%'% mem.percent)
print('swap 内存:', psutil.swap_memory())
输出结果如下:
系统内存: svmem(total=8494747648, available=4726083584, percent=44.4, used=3768664064, free=4726083584)
总 内存:8101M 7.911350G
空闲内存:4507M 4.401508G
使用内存:3594M 3.509842G
未使用内存:4507M 4.401508G
内存使用率:44%
swap 内存: sswap(total=14668763136, used=5127331840, free=9541431296, percent=35.0, sin=0, sout=0)
1.4 获取系统磁盘
实际工作中我们需要关注硬盘空间及IO读写,如果硬盘空间不足就需要添加硬盘或者动态扩容,硬盘相应的方法如下:
方法 | 说明 |
---|---|
disk_partitions(all=False) | 获取硬盘分区信息,返回分区列表 |
disk_usage(path) | 获取硬盘使用情况,path为路径 |
disk_io_counters(perdisk=False, nowrap=True) | 硬盘IO读取信息 |
下面我们实际操作下:
import psutil
#获取硬盘分区
devs = psutil.disk_partitions()
#显示硬盘信息:
print(devs)
#硬盘名称与挂载点,文件类型:
for dev in devs:
print('硬盘名:%s, 挂载点:%s, 文件类型:%s'%(dev.device, dev.mountpoint, dev.fstype))
输出结果如下:
[sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='E:\\', mountpoint='E:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='F:\\', mountpoint='F:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='G:\\', mountpoint='G:\\', fstype='NTFS', opts='rw,fixed')]
硬盘名:C:\, 挂载点:C:\, 文件类型:NTFS
硬盘名:D:\, 挂载点:D:\, 文件类型:NTFS
硬盘名:E:\, 挂载点:E:\, 文件类型:NTFS
硬盘名:F:\, 挂载点:F:\, 文件类型:NTFS
硬盘名:G:\, 挂载点:G:\, 文件类型:NTFS
下面使用disk_usage方法来获取G盘使用情况:
#根据前面打印信息G盘使用'G:\'表示
print(psutil.disk_usage('G:\'))
实际输出结果:
File "", line 2
print(psutil.disk_usage('G:\'))
^
SyntaxError: EOL while scanning string literal
因为Python解释器将\'转义为单引号,所有会报错,在这里我们表示\表示反斜杠;
修改后代码:
import psutil
#定义函数,参数为路径
def showDiskInfo(path):
G = 1024*1024*1024
diskinfo = psutil.disk_usage(path)
print(path, diskinfo)
#将字节转换成G
print('%s 大小: %dG, 已使用: %dG, 未使用: %dG, 使用百分比:%d%%'%\
(path, diskinfo.total//G, diskinfo.used//G, diskinfo.free//G,diskinfo.percent))
showDiskInfo('G:\\')
输出结果:
G:\ sdiskusage(total=188978556928, used=166646931456, free=22331625472, percent=88.2)
G:\ 大小: 175G, 已使用: 155G, 未使用: 20G, 使用百分比:88%
下面我们查看每个硬盘信息:
import psutil
#定义函数,参数为路径
def showDiskInfo(path):
G = 1024*1024*1024
diskinfo = psutil.disk_usage(path)
#将字节转换成G
print('%s 大小: %dG, 已使用: %dG, 未使用: %dG, 使用百分比:%d%%'%\
(path, diskinfo.total//G, diskinfo.used//G, diskinfo.free//G,diskinfo.percent))
#获取硬盘分区
devs = psutil.disk_partitions()
for dev in devs:
#分别显示每个
showDiskInfo(dev.device)
输出结果:
C:\ 大小: 118G, 已使用: 66G, 未使用: 51G, 使用百分比:56%
D:\ 大小: 117G, 已使用: 10G, 未使用: 107G, 使用百分比:8%
E:\ 大小: 150G, 已使用: 58G, 未使用: 92G, 使用百分比:38%
F:\ 大小: 149G, 已使用: 71G, 未使用: 78G, 使用百分比:47%
G:\ 大小: 175G, 已使用: 155G, 未使用: 20G, 使用百分比:88%
这样每个硬盘使用情况我们都清楚了。
最后我们来看硬盘读写,主要信息为:读写数,读写字节,读写时间,操作如下:
import psutil
diskrw = psutil.disk_io_counters()
#diskrw为硬盘总的读写信息
print(diskrw)
diskrws = psutil.disk_io_counters(perdisk=True)
#diskrws为字典类型,表示每个分区读写信息,观察diskrw与diskrws值的关系
print(diskrws)
输出信息:
sdiskio(read_count=2702580, write_count=3112627, read_bytes=92492292608, write_bytes=72206786048, read_time=2702, write_time=3049)
{'PhysicalDrive0': sdiskio(read_count=98229, write_count=392179, read_bytes=8924618240, write_bytes=4908920832, read_time=37, write_time=289), 'PhysicalDrive1': sdiskio(read_count=2604351, write_count=2720448, read_bytes=83567674368, write_bytes=67297865216, read_time=2665, write_time=2760)}
通过这些方法我们可以监控硬盘使用情况,如果硬盘空间不足,可以通过邮件报警,发送邮件方法我们后面章节详细讲解。
1.5 获取进程信息
计算机中,每个程序都是一个进程或者多个进程,除去系统占用资源其他都被这些进程占用,比如我们的web服务,数据库等;很多情况下因为程序自身问题,会导致CPU运行100%,内存耗尽,磁盘写满,最后导致服务崩溃,我们可以通过psutil下面2个方法获取进程相关信息,主要方法如下:
方法 | 说明 |
---|---|
psutil.pids() | 获取进程ID(每个进程都有唯一ID) |
psutil.Process(pid) | 根据进程ID获取进程Process对象 |
实际操作:
import psutil
#获取当前所有进程
pids = psutil.pids()
print(pids)
#获取ID为pids[0]的进程,
process = psutil.Process(pids[0])
print(process)
输出结果:
[0, 4, 120, 440, 624, 736, 744, ... ...]
psutil.Process(pid=0, name='System Idle Process', started='19:55:14')
结果中可以看到,进程的ID为0, 名称为'System Idle Process';
我们再来看Process对象属性(不同系统方法可能不同):
import psutil
#主要信息:进程名,状态,创建时间,CPU内存使用情况,线程数
p = psutil.Process(0)
print('进程名称:', p.name()) #进程名称
print('运行状态:', p.status()) #当前状态
print('创建时间:', p.create_time()) #创建时间
print('CPU信息:', p.cpu_times()) #进程的cpu时间信息,主要:user,system运行时间
print('内存信息:', p.memory_percent())#进程内存利用率
print('内存使用:', p.memory_info()) #进程内存使用详情
print('IO信息:', p.io_counters() ) #进程的IO信息,包括读写IO数字及参数
print('线程数:', p.num_threads() ) #进程开启的线程数
输出结果如下:
进程名称: System Idle Process
运行状态: running
创建时间: 1543290248.0
CPU信息: pcputimes(user=0.0, system=367377.99999999994, children_user=0.0, children_system=0.0)
内存信息: 4.969912151832804e-05
内存使用: pmem(rss=4096, vms=0, num_page_faults=2, peak_wset=4096, wset=4096, peak_paged_pool=0, paged_pool=0, peak_nonpaged_pool=0, nonpaged_pool=0, pagefile=0, peak_pagefile=0, private=0)
IO信息: pio(read_count=0, write_count=0, read_bytes=0, write_bytes=0, other_count=0, other_bytes=0)
线程数: 4
p.memory_info()返回pmem对象,其中rss为进程实际使用内存大小;
所有评论(0)