psutil介绍
psutil(python系统和流程实用程序)是一个跨平台库,用于在Python中检索有关正在运行的 进程和系统利用率(CPU,内存,磁盘,网络,传感器)的信息。它主要用于系统监视,分析,限制进程资源和运行进程的管理。它实现了UNIX命令行工具提供的许多功能,例如:ps,top,lsof,netstat,ifconfig,who,df,kill,free,nice,ionice,iostat,iotop,uptime,pidof,tty,taskset,pmap.
模块的功能
系统相关的类
-
cpu
psutil.cpu_times(percpu=False)
将系统CPU时间作为命名元组返回。每个属性表示CPU在给定模式下花费的秒数.
- user: 正常进程在用户模式下执行所花费的时间.
- system: 在内核模式下执行的进程所花费的时间.
字段说明:
- nice : 在用户模式下执行的niced(优先级)进程所花费的时间.
- iowait: 等待I / O完成所花费的时间.
- irq: 服务硬件中断所花费的时间.
- softirq: 服务软件中断所花费的时间.
- steal: 在虚拟化环境中运行的其他操作系统所花费的时间.
- guest: 在Linux内核的控制下为客户操作系统运行虚拟CPU所花费的时间.
- guest_nice: 运行niced guest虚拟机所花费的时间.
当percpu是True返回一个名为元组的列表在系统上的每个逻辑CPU。列表的第一个元素是指第一个CPU,第二个元素是第二个CPU.
psutil.cpu_percent(interval = None,percpu = False)
返回一个浮点数,表示当前系统范围的CPU利用率百分比.当percpu是True返回表示利用率的浮点数列表,以每个CPU的百分比表示。列表的第一个元素是指第一个CPU,第二个元素是第二个CPU.
In [9]: psutil.cpu_percent(interval=1)
Out[9]: 26.8
In [10]: psutil.cpu_percent(interval=None)
Out[10]: 28.8
In [11]: psutil.cpu_percent(interval=1,percpu=True)
Out[11]: [5.9, 51.0, 25.7, 26.7]
psutil.cpu_times_percent(interval = None,percpu = False) 与cpu_percent() 相同但提供每个特定cpu时间的利用率百分比.
In [13]: psutil.cpu_times_percent(interval=1,percpu=True)
Out[13]:
[scputimes(user=3.0, nice=0.0, system=0.0, idle=97.0, iowait=0.0, irq=0.0, softirq=0.
0, steal=0.0, guest=0.0, guest_nice=0.0),
scputimes(user=2.0, nice=0.0, system=1.0, idle=97.0, iowait=0.0, irq=0.0, softirq=0.
0, steal=0.0, guest=0.0, guest_nice=0.0),
scputimes(user=4.0, nice=0.0, system=1.0, idle=95.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0),
scputimes(user=98.0, nice=0.0, system=1.0, idle=0.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)]
psutil.cpu_count(logical=True) 返回系统中逻辑CPU的数量. 当logical为False时返回物理核心数.
In [14]: psutil.cpu_count(logical=True)
Out[14]: 4
In [17]: psutil.cpu_count(logical=False)
Out[17]: 2
获得可用cpu数量
In [18]: len(psutil.Process().cpu_affinity())
Out[18]: 4
psutil.cpu_stats()
将各种CPU统计信息作为命名元组返回.
- ctx_switches:启动后的上下文切换次数
- interrupts: 自引导以来的中断数.
- soft_interrupts:自引导以来的软件中断次数
- syscalls:自引导以来的系统调用次数。
In [19]: psutil.cpu_stats()
Out[19]: scpustats(ctx_switches=10645749, interrupts=2838571, soft_interrupts=2770642
, syscalls=0)
psutil.cpu_freq(percpu=False) 将CPU频率作为名称包返回,包括 以Mhz表示的当前,最小和最大频率. 当percpu为True并且系统支持每CPU频率检索,为每个CPU返回一个频率列表,否则返回包含单个元素的列表.
In [20]: psutil.cpu_freq(percpu=False)
Out[20]: scpufreq(current=3021.204, min=800.0, max=3100.0)
In [21]: psutil.cpu_freq(percpu=True)
Out[21]:
[scpufreq(current=3010.085, min=800.0, max=3100.0),
scpufreq(current=3086.548, min=800.0, max=3100.0),
scpufreq(current=2993.103, min=800.0, max=3100.0),
scpufreq(current=2993.23, min=800.0, max=3100.0)]
内存相关的类
-
memory
psutil.virtual_memory()
- total: 总物理内存
- available: 在没有系统进入交换的情况下立即提供给进程的内存.
- used: 使用的内存.
- free: 空闲的内存.
- active: 正在使用的内存.
- inactive: 未使用的内存.
- buffers: 缓存文件系统元数据.
- cached: 缓存各种内容.
- shared: 共享内存.
- slab: 内核数据结构缓存
查看物理内存
In [24]: mem = psutil.virtual_memory()
In [25]: mem
Out[25]: svmem(total=12504399872, available=9867579392, percent=21.1, used=206
4056320, free=7957213184, active=2586599424, inactive=1411063808, buffers=2329
23136, cached=2250207232, shared=330375168, slab=357433344)
psutil.swap_memory() 将系统交换内存统计信息作为命名元组返回.
- total: 总交换内存(以字节为单位)
- used: 以字节为单位使用的swap内存
- free: 以字节为单位的自由交换内存.
- 百分比: 计算的百分比使用率(total - available) / total * 100
- sin: 系统从磁盘交换的字节数.
- sout: 系统从磁盘换出的字节数.
磁盘相关的类
-
disk
psutil.disk_partitions(all=False) 将所有已安装的磁盘分区作为命名元组列表返回,包括设备,挂载点和文件系统类型.
psutil.disk_usage(path)
In [32]: psutil.disk_usage('/')
Out[32]: sdiskusage(total=181488431104, used=12284243968, free=159913754624, percent=7.1)
psutil.disk_io_counters(perdisk=False,nowrap=True) 将系统范围的磁盘I / O统计信息作为命名元组返回
- read_count: 读取次数
- write_count: 写入次数.
- read_bytes: 读取的字节数
- write_bytes: 写入的字节数
- read_time: 从磁盘读取的时间(以毫秒为单位).
- write_time: 写入磁盘所花费的时间(以毫秒为单位).
- busy_time: 在实际I/O上的时间.(以毫秒为单位).
- read_merged_count: 合并读取的数量
- write_merged_count: 合并写入次数.
当perdisk为True,系统上安装的每个物理磁盘返回相同的信息,作为字典.分区名称为键,命名元组为值.当nowrap为True,psutil将在函数调用中检测并调整这些数字,并将“旧值”添加到“新值”,以便返回的数字将始终增加或保持不变,但永远不会减少. psutil.disk_io_counters.cache_clear() 用于使nowrap 缓存无效.
In [36]: psutil.disk_io_counters()
In [37]: psutil.disk_io_counters(perdisk=True) # 返回字典,所有磁盘信息.
网络相关的类
-
network
psutil.net_io_counters(pernic=False,nowrap=True) 将系统范围的网络I/O统计信息作为命名元组返回
- bytes_sent:发送的字节数.
- bytes_recv:接收的字节数.
- packets_sent:发送的包数.
- packets_recv:接收的包数.
- errin:接收时的错误总数.
- errout:发送时的错误总数
- dropin:丢弃的传入数据包总数.
- dropout:丢弃的传出数据包总数
当pernic为True,系统上安装的每个网络接口返回相同的信息作为字典,网络接口名称作为键,命名元组为值. psutil.net_io_counters.cache_clear() 用于使nowrap 缓存无效.
In [41]: psutil.net_io_counters()
In [42]: psutil.net_io_counters(pernic=True)
psutil.net_connections(kind='inet') 将系统范围的套接字连接作为命名元组列表返回.
- fd: 套接字文件描述符.
- family:地址簇.
- type:地址类型
- laddr:作为命名元组的本地地址或 AF_UNIX套接字的情况.
- raddr:作为命名元组的远程地址或UNIX套接字的绝对地址
- status:表示TCP连接的状态.
- pid: 打开套接字的进程的PID.
In [45]: psutil.net_connections()
In [45]: psutil.net_connections(kind='inet')
psutil.net_if_addrs() 将与系统上安装的每个NIC(网络接口卡)关联的地址作为字典返回.键为NIC名称,值是分配给NIC的每个地址的命名元组列表.
- family:地址簇.
- address: 主NIC地址
- netmask:网络掩码地址
- broadcast: 广播地址.
- ptp: 点对点接口上的目标地址.
psutil.net_if_stats() 将有关每个NIC(网络接口卡)的信息作为字典返回,键是NIC名称,值是以下字段:
- isup: 指示NIC是否已启动并运行的bool。
- duplex:双工通信类型.
- speed:以兆位(MB)表示的NIC速度
- mtu:NIC的最大传输单位,以字节为单位.
硬件相关的类
-
传感器:
psutil.sensors_temperatures() 返回硬件温度。每个条目都是一个名为元组,代表某个硬件温度传感器.
psutil.sensors_fans() 返回硬件风扇速度,每个条目都是一个名为元组,代表某个硬件传感器风扇。风扇速度以RPM(每分钟轮数)表示.
psutil.sensors_battery() 将电池状态信息作为命名元组返回
- percent:电池剩余百分比
- secsleft: 电池电量耗尽前剩下的秒数的粗略近似值.连接了交流电源线(POWER_TIME_UNLIMITED).
- power_plugged:True 表明连接了交流电源线.
其他系统信息
-
其他系统信息
psutil.boot_time() 返回自纪元以来以秒表示的系统启动时间.
In [52]: import psutil,datetime
In [53]: psutil.boot_time()
Out[53]: 1544831477.0
In [54]:datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:
...: %S")
Out[54]: '2018-12-15 07:51:17'
psutil.users() 将当前在系统上连接的用户作为命名元组列表返回,包含:
- user: 用户名称
- terminal:与用户关联的tty或伪tty.
- host: 相关的主机名.
- start: 创建时间为浮点数,以纪元为单位,以秒为单位.
- pid: 登录过程的PID.
In [56]: psutil.users()
process相关的类
-
process
psutil.pids() 返回当前运行的PID列表。
psutil.process_iter(attrs=None,ad_value=None) 返回一个迭代器Process,为本地计算机上的所有正在运行的进程生成一个类实例。每个实例只创建一次,然后缓存到内部表中,每次生成一个元素时都会更新。Process检查缓存实例的身份,以便在其他进程重用PID时保证安全.
In [59]: import psutil
In [60]: for proc in psutil.process_iter():
...: try:
...: pinfo = proc.as_dict(attrs=['pid','name','username'])
...: except psutil.NoSuchProcess:
...: pass
...: else:
...: print(pinfo)
...:
{'name': 'systemd', 'pid': 1, 'username': 'root'}
{'name': 'kthreadd', 'pid': 2, 'username': 'root'}
{'name': 'kworker/0:0H', 'pid': 4, 'username': 'root'}
使用attrs参数的更紧凑版本:
In [62]: for proc in psutil.process_iter(attrs=['pid','name','username']):
...: print(proc.info)
用于创建数据结构的dict:
In [63]: procs = {p.pid: p.info for p in psutil.process_iter(attrs=['name','username'])}
In [64]: procs
显示如何按名称过滤进程:
In [66]: [p.info for p in psutil.process_iter(attrs=['pid','name']) if 'python' in p.info['name']]
psutil.pid_exists(pid) 检查当前进程列表中是否存在给定的PID. 或者: pid in psutil.pids().
psutil.wait_procs(procs,timeout = None,callback = None) 等待Process实例列表终止的便捷功能。返回一个元组,指示哪些进程已经消失,哪些进程仍然存在。该走的人都会有一个新的 返回码属性,指示进程的退出状态.
终止并等待此进程的所有子进程
import psutil
def on_terminate(proc):
print("process {} terminated with exit code {}".format(proc, proc.returncode))
procs = psutil.Process().children()
for p in procs:
p.terminate()
gone, alive = psutil.wait_procs(procs, timeout=3, callback=on_terminate)
for p in alive:
p.kill()
异常的类
进程类
-
进程类
class psutil.Process 表示具有给定pid的OS进程.
oneshot() 实用程序上下文管理器.可以显着加快多个进程信息的检索速度
In [80]: p = psutil.Process()
In [81]: with p.oneshot():
...: p.name()
...: p.cpu_times()
...: p.cpu_percent()
...: p.create_time()
...: p.ppid()
...: p.status()
oneshot的方法:
cpu_num()
cpu_percent()
create_time()
name()
ppid()
status()
terminal()
gids()
num_ctx_switches()
num_threads()
uids()
username()
memory_full_info()
memory_maps()
-
pid:
过程pid,该类的唯一只读属性.
-
ppid()
进程父PID
-
name()
进程名称
-
exe()
该进程可作为绝对路径执行.
In [82]: import psutil
In [83]: psutil.Process().exe()
Out[83]: '/services/devopsinstall/python3.6/bin/python3.6'
-
cmdline()
此过程的命令行已作为字符串列表调用
In [85]: psutil.Process().cmdline()
Out[85]:
['/services/devopsinstall/python3.6/bin/python3.6',
'/services/devopsinstall/python3.6/bin/ipython']
-
environ()
作为dict的进程的环境变量.
In [87]: psutil.Process().environ()
-
create_time()
流程创建时间为浮点数. 以UTC为单位. 以秒为单位表示.
In [88]: import psutil,datetime
In [89]: p = psutil.Process()
In [90]: p.create_time()
Out[90]: 1544833282.8
In [91]: datetime.datetime.fromtimestamp(p.create_time()).strftime("%Y-%m-%d %H:%M:%S"
...: )
Out[91]: '2018-12-15 08:21:22'
-
as_dict (attrs=None,ad_value=None)
实用方法将多个流程信息检索为字典.
In [92]: import psutil
In [93]: p = psutil.Process()
In [94]: p.as_dict(attrs=['pid','name','username'])
Out[94]: {'name': 'ipython', 'pid': 6296, 'username': 'liyuanjie'}
-
parent()
将父进程作为Process 对象返回的实用方法,抢先检查PID是否已被重用.
-
status()
当前进程状态为字符串.
-
cwd()
进程当前工作目录为绝对路径.
-
username()
拥有该进程的用户的名称.
-
uids()
有效和保存的用户ID作为命名元组.
-
gids()
有效和保存的组ID作为命名元组.
-
terminal()
与此过程关联的终端.
-
nice
获取或设置进程的优先级.
In [95]: import psutil
In [96]: p = psutil.Process()
In [97]: p.nice(10)
In [98]: p.nice()
Out[98]: 10
-
ionice(inclass=None,value=None)
获取或设置进程I/O优先级.
In [99]: import psutil
In [100]: p = psutil.Process()
In [101]: p.ionice(psutil.IOPRIO_CLASS_IDLE)
In [102]: p.ionice()
Out[102]: pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
资源相关的类
-
rlimit()
获取或设置进程资源限制
In [103]: import psutil
In [104]: p = psutil.Process()
In [105]: p.rlimit(psutil.RLIMIT_NOFILE,(128,128))
In [106]: p.rlimit(psutil.RLIMIT_FSIZE,(1024,1024))
In [107]: p.rlimit(psutil.RLIMIT_FSIZE)
Out[107]: (1024, 1024)
In [108]: p
Out[108]: psutil.Process(pid=6296, name='ipython', started='08:21:22')
-
io_counters()
将进程I/O统计信息作为命名元组返回
- read_count:执行的读取操作数.
- write_count:执行的写操作次数.
- read_bytes:读取的字节数
- write_bytes:写入的字节数.
- read_chars: 此进程传递给的字节数read和pread的累积.
- write_chars: 此进程传递给的字节数write和pwrite的累积.
In [109]: import psutil
In [110]: p = psutil.Process()
In [111]: p.io_counters()
Out[111]: pio(read_count=58545, write_count=81420, read_bytes=921600, write_bytes=2277
376, read_chars=10377708, write_chars=2828564)
-
num_ctx_switches()
由此过程执行的自愿和非自愿上下文切换次数.
-
num_fds()
此进程当前打开的文件描述符数
-
num_handles()
此进程当前使用的句柄数.
-
num_threads()
此进程当前使用的线程数.
-
threads()
将进程打开的线程返回为命名元组列表,包括线程ID和线程CPU时间.
-
cpu_times()
返回一个名为tuple 的(user,system,children_user,children_system),表示累积的进程时间,以秒为单位.
-
cpu_percent(interval=None)
返回一个浮点数,表示进程CPU利用率百分比,也可以是进程在不同CPU上运行多个线程的情况。.
In [112]: import psutil
In [113]: p = psutil.Process()
In [114]: p.cpu_percent(interval=1)
Out[114]: 0.0
In [115]: p.cpu_percent(interval=None)
Out[115]: 10.0
-
cpu_affinity(cpus=)
获取或设置进程当前 CPU关联。CPU亲和性包括告诉操作系统仅在一组有限的CPU上运行进程.
In [116]: import psutil
In [117]: psutil.cpu_count()
Out[117]: 4
In [118]: p = psutil.Process()
In [119]: p.cpu_affinity()
Out[119]: [0, 1, 2, 3]
In [120]: p.cpu_affinity([0,1])
In [121]: p.cpu_affinity()
Out[121]: [0, 1]
In [122]: p.cpu_affinity([])
-
cpu_num()
返回当前正在运行此进程的CPU. 可结合使用psutil.cpu_percent(percpu=True)来观察分布在多个CPU上的系统工作负载.
-
memory_info ()
返回具有可变字段的命名元组.
- rss: 进程使用的非交换物理内存.
- vms: 进程使用的虚拟内存总量.
- shared: 与其他进程共享的内存.
- text: 用于可执行代码的内存量.
- data: 用于可执行代码以外的物理内存量.
- lib: 共享库使用的内存.
- dirty: 脏页的数量.
In [123]: import psutil
In [124]: p = psutil.Process()
In [125]: p.memory_info()
Out[125]: pmem(rss=77422592, vms=2310541312, shared=9818112, text=5578752, lib=0, data
=121827328, dirty=0)
-
memory_full_info()
此方法返回相同的信息memory_info().
- uss: 一个进程独有的内存.表示当前进程终止时将释放的内存量.
- pss: 是与其他进程共享的内存量.
- swap: 已换出磁盘的内存量.
In [126]: import psutil
In [127]: p = psutil.Process()
In [128]: p.memory_full_info()
Out[128]: pfullmem(rss=77365248, vms=2310541312, shared=9818112, text=5578752, lib=0,
data=121827328, dirty=0, uss=72835072, pss=73095168, swap=0)
-
memory_percent(memtype="rss")
将进程内存与总物理系统内存进行比较,并以百分比形式计算进程内存利用率.
-
memory_maps(grouped=True)
将进程的映射内存区域返回为命名元组的列表,其字段根据平台而变化.
In [130]: p = psutil.Process()
In [131]: p.memory_maps()
In [133]: p.memory_maps(grouped=False)
-
children(recursive = False)
将此进程的子节点作为Process 实例列表返回.
p.children(recursive=True)
-
open_files()
将进程打开的常规文件作为命名元组列表返回.
In [147]: p = psutil.Process()
In [148]: p.open_files()
-
connections(kind="inet")
返回由进程打开的套接字连接作为命名元组的列表.
- fd: 套接字文件描述符.
- family: 地址簇.
- type: 地址类型.
- laddr: 作为命名元组的本地地址.
- raddr: 作为命名元组的远程地址.
- status: 表示TCP连接的状态.
In [162]: p = psutil.Process(20191)
In [163]: p.name()
Out[163]: 'firefox'
In [164]: p.connections()
-
is_running()
返回当前进程是否在当前进程列表中运行.
-
send_signal()
发送信号进行处理.
-
suspend()
使用SIGSTOP信号暂停进程执行.
-
resume()
使用SIGCONT信号恢复进程执行.
-
terminate()
使用SIGTERM信号终止进程.
-
kill()
使用SIGKILL信号抢占当前进程.
-
wait()
等待进程终止.
In [165]: p = psutil.Process(20191)
In [166]: p.terminate()
In [167]: p.wait()
In [168]: p
Out[168]: psutil.Process(pid=20191, status='terminated')
Popen类
-
Popen类
psutil.Popen
In [1]: import psutil
In [2]: from subprocess import PIPE
In [3]: p = psutil.Popen(["/usr/bin/python3","-c","print('yuanjie')"],stdout=PIPE)
In [4]: p.name()
Out[4]: 'python3'
In [5]: p.username()
Out[5]: 'liyuanjie'
In [6]: p.communicate()
Out[6]: (b'yuanjie\n', None)
In [7]: p.wait(timeout=2)
Out[7]: 0
psutil.Popen通过with语句支持对象作为上下文管理器:在退出时,将关闭标准文件描述符,并等待进程.
In [8]: import psutil,subprocess
In [9]: with psutil.Popen(["ifconfig"],stdout=subprocess.PIPE) as proc:
...: log.write(proc.stdout.read())
过滤和排序过程
-
过滤和排序过程
这是一个单行的集合,显示如何使用process_iter()以过滤流程并对其进行排序.
- 查找名称中包含python的进程
In [12]: import psutil
In [13]: from pprint import pprint as pp
In [14]: pp([p.info for p in psutil.process_iter(attrs=['pid','name']) if 'python' in p.info['name']]) [{'name': 'python3.6', 'pid': 14942}, {'name': 'python3.6', 'pid': 14946}, {'name': 'ipython', 'pid': 22123}]
用户拥有的进程: In [15]: import getpass
In [16]: pp([(p.pid,p.info['name']) for p in psutil.process_iter(attrs=['name','username']) if p.info['username'] == getpass.getuser()])
[(1751, 'systemd'), (1752, '(sd-pam)'), (1765, 'gnome-keyring-daemon'),
进程积极运行: In [17]: pp([(p.pid,p.info) for p in psutil.process_iter(attrs=['name','status']) if p.info['status'] == psutil.STATUS_RUNNING])
[(22123, {'name': 'ipython', 'status': 'running'})]
使用日志文件的进程
- 使用日志文件的进程:
```
In [18]: import os,psutil
In [20]: for p in psutil.process_iter(attrs=['name','open_files']):
...: for file in p.info['open_files'] or []:
...: if os.path.splitext(file.path)[1] == '.log':
...: print("%-5s %-10s %s" % (p.pid,p.info['name'][:10],file.path))
```
消耗超过500M内存的进程
```
消耗超过500M内存的进程:
In [21]: pp([(p.pid,p.info['name'],p.info['memory_info'].rss) for p in psutil.process_iter(attrs=['name','memory_info']) if p.info['memory_info'].rss > 500 * 1024 * 1024])
消耗最多的3个进程: In [22]: pp([(p.pid,p.info) for p in sorted(psutil.process_iter(attrs=['name','memory_percent']),key=lambda p: p.info['memory_percent'])][-3:]) ```
消耗最多CPU时间的前3个进程
-
消耗最多CPU时间的前3个进程:
In [23]: pp([(p.pid,p.info['name'],sum(p.info['cpu_times'])) for p in sorted(psutil.process_iter(attrs=['name','cpu_times']),key=lambda p: sum(p.info['cpu_times'][:2]))][-3:])
导致I/O最多的前3个进程
-
导致I/O最多的前3个进程
执行错误, 报错:
pp([(p.pid, p.info['name']) for p in sorted(psutil.process_iter(attrs=['name', 'io_counters']), key=lambda p: p.info['io_counters'] and p.info['io_counters'][:2])][-3:])
TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'
打开更多文件描述符的前3个进程
-
打开更多文件描述符的前3个进程:
pp([(p.pid, p.info) for p in sorted(psutil.process_iter(attrs=['name', 'num_fds']), key=lambda p: p.info['num_fds'])][-3:])
报错: TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'
psutil脚本的github地址
|