参考官方文档:https://pypi.org/project/psutil/
psutil是一个开源且跨平台(http://code.google.com/p/psutil/)的库,能够轻松实现**获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要应用于系统监控,分析和限制系统资源及进程的管理。它实现了同等命令行工具提供的功能,**如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、ionice、iostat、iotop、uptime、pidof、tty、taskset、pmap等。
在Python中获取系统信息的另一个好办法是使用psutil
这个第三方模块。还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。
Works with Python versions from 2.4 to 3.X.
CentOS安装psutil包:
python版本:5.8
wget https://pypi.python.org/packages/source/p/psutil/psutil-5.8.0.tar.gz
tar zxvf psutil-5.8.0.tar.gz
cd psutil-5.8.0
yum -y install python-devel (如果提示缺少python.h头文件,执行此命令。)
python setup.py install
Windos安装psutil包:
root@shawn:~# pip3 install psutil
Collecting psutil
Downloading psutil-5.8.0-cp38-cp38-manylinux2010_x86_64.whl (296 kB)
|████████████████████████████████| 296 kB 20 kB/s
Installing collected packages: psutil
Successfully installed psutil-5.8.0
psutil.cpu_times()
方法psutil.cpu_times()
获取CPU的完整信息>>> import psutil
>>> psutil.cpu_times()
scputimes(user=733.23, nice=2.62, system=122.87, idle=19414.35, iowait=29.46, irq=0.0, softirq=34.18, steal=0.0, guest=0.0, guest_nice=0.0)
>>> psutil.cpu_times().user
793.19
>>> psutil.cpu_times().iowait
31.79
psutil.cpu_count()
获取CPU个数psutil.cpu_count()
获取CPU逻辑个数#cpu_count(,[logical]):默认返回逻辑CPU的个数,当设置logical的参数为False时,返回物理CPU的个数。
>>> psutil.cpu_count()
8
使用psutil.cpu_count(logical=False)
获取CPU的物理个数,默认logical值为True
>>> psutil.cpu_count(logical=False)
8
psutil.getloadavg()
获取平均系统负载psutil.getloadavg()
可以获取平均系统负载,会以元组的形式返回最近1、5和15分钟内的平均系统负载。 在Windows上,这是通过使用Windows API模拟的,该API产生一个线程,该线程保持在后台运行,并每5秒更新一次结果,从而模仿UNIX行为。 因此,在Windows上,第一次调用此方法,在接下来的5秒钟内,它将返回无意义的(0.0,0.0,0.0)元组。
>>> psutil.getloadavg()
(1.22, 1.41, 1.38)
psutil.cpu_percent()
获取CPU使用率cpu_percent(,[percpu],[interval])
:返回CPU的利用率
interval
:指定的是计算cpu使用率的时间间隔,interval不为0时,则阻塞时显示interval执行的时间内的平均利用率
percpu
:指定是选择总的使用率或者每个cpu的使用率,percpu
为True
时显示所有物理核心的利用率
1.指定的是计算cpu使用率的时间间隔
>>> for x in range(10):
... psutil.cpu_percent(interval=1)
...
2.4
2.5
2.7
2.3
2.5
2.2
2.0
2.2
2.4
2.2
2.实现类似top命令的CPU使用率,每秒刷新一次,累计10次:
>>> for x in range(10):
... psutil.cpu_percent(interval=1,percpu=True)
...
[1.0, 3.1, 5.0, 4.0, 0.0, 4.0, 3.0, 2.0]
...
[1.0, 1.0, 6.1, 3.1, 2.0, 2.1, 0.0, 0.0]
[2.0, 1.0, 6.0, 4.9, 1.0, 5.1, 1.0, 1.0]
psutil.cpu_stats()
获取CPU的统计信息cpu_stats()以命名元组的形式返回CPU的统计信息,包括上下文切换,中断,软中断和系统调用次数。
>>> psutil.cpu_stats()
scpustats(ctx_switches=3928927, interrupts=2319133, soft_interrupts=1974116, syscalls=0)
psutil.cpu_freq()
获取CPU频率>>> psutil.cpu_freq()
scpufreq(current=1799.999, min=0.0, max=0.0)
psutil.cpu_times_percent()
获取耗时比例>>> psutil.cpu_times_percent()
scputimes(user=0.1, nice=0.0, system=0.0, idle=99.9, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
psutil.virtual_memory()
内存使用情况psutil.virtual_memory()
:获取系统内存的使用情况,以命名元组的形式返回内存使用情况,包括总内存,可用内存,内存利用率,buffer和cache等。单位为字节。获取内存的完整信息
>>> psutil.virtual_memory()
svmem(total=2028425216, available=982532096, percent=51.6, used=861827072, free=810414080, active=401735680, inactive=431902720, buffers=4096, cached=356179968, shared=9203712, slab=236351488)
'''
返回的是字节Byte为单位的整数
重点关注的参数是:
1.total表示内存总的大小
2.percent表示实际已经使用的内存占比。
3.available表示还可以使用的内存。
4.uused表示已经使用的内存
'''
使用total获取内存总大小
>>> psutil.virtual_memory().total
2028425216
使用获取已经使用的内存
>>> psutil.virtual_memory().used
865882112
使用free获取剩余的内存
>>> psutil.virtual_memory().free
805871616
psutil.swap_memory()
获取系统交换内存(swap)的统计信息psutil.swap_memory()
:获取系统交换内存的统计信息,以命名元组的形式返回swap/memory
使用情况,包含swap中页的换入和换出。获取交换分区相关
>>> psutil.swap_memory()
sswap(total=4091539456, used=173793280, free=3917746176, percent=4.2, sin=23683072, sout=188874752)
磁盘信息主要两部分,一个是磁盘的利用率,一个是io。
disk_partitions([all=False]):以命名元组的形式返回所有已挂载的磁盘,包含磁盘名称,挂载点,文件系统类型等信息。
当all等于True时,返回包含/proc等特殊文件系统的挂载信息
获取磁盘分区的信息
>>> psutil.disk_partitions()
[sdiskpart(device='/dev/sda3', mountpoint='/', fstype='xfs', opts='rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota', maxfile=255, maxpath=4096), sdiskpart(device='/dev/loop1', mountpoint='/snap/core18/1944', fstype='squashfs', opts='ro,nodev,relatime', maxfile=256, maxpath=4096),。...sdiskpart(device='/dev/loop6', mountpoint='/snap/snap-store/467', fstype='squashfs', opts='ro,nodev,relatime', maxfile=256, maxpath=4096), sdiskpart(device='/dev/sda1', mountpoint='/boot', fstype='xfs', opts='rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota', maxfile=255, maxpath=4096)]
>>> io = psutil.disk_partitions()
>>> print(io[-1])
sdiskpart(device='/dev/sr0', mountpoint='/media/shawn/Ubuntu 20.04.1 LTS amd64', fstype='iso9660', opts='ro,nosuid,nodev,relatime,nojoliet,check=s,map=n,blocksize=2048,uid=1000,gid=1000,dmode=500,fmode=400', maxfile=255, maxpath=4096)
>>>
获取根分区的使用情况
>>> psutil.disk_usage('/')
sdiskusage(total=101184290816, used=8805330944, free=92378959872, percent=8.7)
>>>
disk_io_counters
获取io统计信息获取磁盘总的io个数,读写信息
>>> psutil.disk_io_counters()
sdiskio(read_count=60919, write_count=448417, read_bytes=1582292480, write_bytes=31438750208, read_time=50157, write_time=259374, read_merged_count=2527, write_merged_count=44226, busy_time=1096900)
'''补充说明
read_count(读IO数)
write_count(写IO数)
read_bytes(读IO字节数)
write_bytes(写IO字节数)
read_time(磁盘读时间)
write_time(磁盘写时间)
'''
获取单个分区的IO和读写信息
>>> psutil.disk_io_counters(perdisk=True)
{
'loop0': sdiskio(read_count=43, write_count=0, read_bytes=358400, write_bytes=0, read_time=28, write_time=0, read_merged_count=0, write_merged_count=0, busy_time=44), 'loop1': sdiskio(read_count=424, write_count=0, read_bytes=6236160, write_bytes=0, read_time=277, write_time=0, read_merged_count=0, write_merged_count=0, busy_time=956),... write_merged_count=985, busy_time=1132488)}
psutil.net_io_counter([pernic])
获取网卡io统计信息 获取网络读写字节/包的个数
>>> psutil.net_io_counters()
snetio(bytes_sent=242309, bytes_recv=6775236, packets_sent=2563, packets_recv=44703, errin=0, errout=0, dropin=9301, dropout=0)
列出所有网卡的统计信息
>>> psutil.net_io_counters(pernic=True)
{
'lo': snetio(bytes_sent=38379, bytes_recv=38379, packets_sent=413, packets_recv=413, errin=0, errout=0, dropin=0, dropout=0), 'ens32': snetio(bytes_sent=203930, bytes_recv=6756079, packets_sent=2150, packets_recv=44430, errin=0, errout=0, dropin=9334, dropout=0)}
psutil.net_if_addrs()
获取网络接口信息>>> psutil.net_if_addrs()
{
'lo': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_PACKET: 17>, address='00:00:00:00:00:00', netmask=None, broadcast=None, ptp=None)], 'ens32': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.12.154', netmask='255.255.255.0', broadcast='192.168.12.255', ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 10>, address='fe80::1c00:63d1:f5bf:1cec%ens32', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_PACKET: 17>, address='00:0c:29:7a:81:66', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
>>> psutil.net_if_stats()
{
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536), 'ens32': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500)}
>>> psutil.net_connections()
Traceback (most recent call last):
...
PermissionError: [Errno 1] Operation not permitted
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
...
psutil.AccessDenied: psutil.AccessDenied (pid=3847)
你可能会得到一个AccessDenied错误,原因是psutil获取信息也是要走系统接口,而获取网络连接信息需要root权限,这种情况下,可以退出Python交互环境,用sudo重新启动:
$ sudo python3
Password: ******
Python 3.6.3 ... on darwin
Type "help", ... for more information.
>>> import psutil
>>> psutil.net_connections()
[
sconn(fd=83, family=<AddressFamily.AF_INET6: 30>, type=1, laddr=addr(ip='::127.0.0.1', port=62911), raddr=addr(ip='::127.0.0.1', port=3306), status='ESTABLISHED', pid=3725),
sconn(fd=84, family=<AddressFamily.AF_INET6: 30>, type=1, laddr=addr(ip='::127.0.0.1', port=62905), raddr=addr(ip='::127.0.0.1', port=3306), status='ESTABLISHED', pid=3725),
sconn(fd=93, family=<AddressFamily.AF_INET6: 30>, type=1, laddr=addr(ip='::', port=8080), raddr=(), status='LISTEN', pid=3725),
sconn(fd=103, family=<AddressFamily.AF_INET6: 30>, type=1, laddr=addr(ip='::127.0.0.1', port=62918), raddr=addr(ip='::127.0.0.1', port=3306), status='ESTABLISHED', pid=3725),
sconn(fd=105, family=<AddressFamily.AF_INET6: 30>, type=1, ..., pid=3725),
sconn(fd=106, family=<AddressFamily.AF_INET6: 30>, type=1, ..., pid=3725),
sconn(fd=107, family=<AddressFamily.AF_INET6: 30>, type=1, ..., pid=3725),
...
sconn(fd=27, family=<AddressFamily.AF_INET: 2>, type=2, ..., pid=1)
]
psutil.net_connections()
网络连接的详细信息inet 代表 IPv4 and IPv6
>>> psutil.net_connections(kind='inet')
[sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.12.154', port=58478)...sconn(fd=-1, family=<AddressFamily.AF_INET6: 10>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='::1', port=631), raddr=(), status='LISTEN', pid=None)]
>>>
以linux时间格式返回,可以使用时间戳转换
>>> import psutil
>>> psutil.boot_time()
1610705729.0
转换成自然时间格式
>>> import psutil
>>> psutil.boot_time()
1610705729.0
>>> import datetime
>>> datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H: %M: %S")
'2021-01-15 18: 15: 29'
使用psutil.users()
可以获取当前连接的系统用户列表
>>> import psutil
>>> psutil.users()
[suser(name='shawn', terminal=':0', host='localhost', started=1610705792.0, pid=1442)]
>>> for u in psutil.users():
... print(u)
...
suser(name='shawn', terminal=':0', host='localhost', started=1610705792.0, pid=1442)
>>> u.name
'shawn'
>>> u.terminal
':0'
>>> u.host
'localhost'
>>> u.started
1610705792.0
>>>
psutil模块还未我们提供了可以查看获取计算机硬件、电池状态、硬件风扇速度等。
>>> import psutil
返回硬件的信息
>>> psutil.sensors_temperatures()
{
'acpitz': [shwtemp(label='', current=47.0, high=103.0, critical=103.0)],
'asus': [shwtemp(label='', current=47.0, high=None, critical=None)],
'coretemp': [shwtemp(label='Physical id 0', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 0', current=45.0, high=100.0, critical=100.0)]}
>>>
返回电池状态
>>> psutil.sensors_fans()
{
'asus': [sfan(label='cpu_fan', current=3200)]}
>>>
返回硬件风扇速度
>>> psutil.sensors_battery()
sbattery(percent=93, secsleft=16628, power_plugged=False)
>>>
返回硬件温度
>>> psutil.sensors_temperatures(fahrenheit=False)
psutil.pids
获取系统全部进程以列表的形式返回当前正在运行的进程
>>> psutil.pids()
[1, 2, 3, 4, 6, 9, 10, 11, 12, 13, 14,
...
3929, 3930, 3949, 3955, 3975, 3989, 4564, 4619, 4625, 4626]
psutil.Process()
方法查看系统单个进程>>> p = psutil.Process(8216) #获取当前指定进程ID
>>> p.name() #进程名
'bash'
>>> p.exe() #进程的bin路径
'/usr/bin/bash'
>>> p.cwd() #进程的工作目录绝对路径
'/root'
>>> p.cmdline() # 进程启动的命令行
['bash']
>>> p.ppid() # 父进程ID
8215
>>> p.parent() # 父进程
psutil.Process(pid=8215, name='su', status='sleeping', started='22:59:40')
>>> p.children() # 子进程列表
[psutil.Process(pid=8224, name='python3', status='running', started='22:59:56')]
>>> p.num_threads() #进程的子进程个数
1
>>> p.status() #进程状态
'sleeping'
>>> p.create_time() #进程创建时间
1610722781.1
>>> p.uids() #进程uid信息
puids(real=0, effective=0, saved=0)
>>> p.gids() #进程的gid信息
pgids(real=0, effective=0, saved=0)
>>> p.cpu_times() #进程使用cpu时间信息,包括user,system两个cpu信息
pcputimes(user=0.0, system=0.01, children_user=0.01, children_system=0.0, iowait=0.0)
>>> p.cpu_affinity() #get进程cpu亲和度,如果要设置cpu亲和度,将cpu号作为参考就好
[0, 1, 2, 3, 4, 5, 6, 7]
>>> p.memory_percent() #进程内存利用率
0.19627600606597861
>>> p.memory_info() #进程使用的内存rss,vms信息
pmem(rss=3981312, vms=13230080, shared=3432448, text=724992, lib=0, data=712704, dirty=0)
>>> p.io_counters() #进程的IO信息,包括读写IO数字及参数
pio(read_count=140, write_count=28, read_bytes=180224, write_bytes=0, read_chars=66146, write_chars=1759)
>>> p.connections() # 进程相关网络连接
[]
>>> p.num_threads() #进程开启的线程数
1
>>> p.threads() # 所有线程信息
[pthread(id=8216, user_time=0.0, system_time=0.01)]
>>> p.terminal() # 进程终端
'/dev/pts/1'
>>> p.open_files() # 进程打开的文件
[]
>>> p.environ() # 进程环境变量
{
'SHELL': '/bin/bash', 'PATH': '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:...', 'PWD': '/Users/michael', 'LANG': 'zh_CN.UTF-8', ...}
>>> p.terminate() # 发送SIGTEAM信号结束进程
Terminated: 15
>>> p.kill() #发送SIGKILL信号结束进程
>>> 已杀死
>>> p.is_running() #进程是否在运行
True
>>> p.num_fds() #进程打开的文件个数
4
>>> p.is_running() #判断进程是否正在运行
True
popen
方法的使用:获取(跟踪)用户启动的应用程序进程信息
>>> import psutil
>>> from subprocess import PIPE
>>> p = psutil.Popen(["/usr/bin/python3", "-c", "print('hello')"],stdout=PIPE)
>>> p.name()
'python3'
>>> p.username()
'shawn'
>>> p.communicate()
(b'hello\n', None)
>>> p.wait(timeout=2)
0
1.psutil.pid_exists判断给点定的pid是否存在
>>> psutil.pid_exists(1)
True
2.psutil.process_iter迭代当前正在运行的进程,返回的是每个进程的Process对象
>>> psutil.process_iter(8216)
<generator object process_iter at 0x7f48a7275040>
psutil还提供了一个test()
方法,可以模拟出ps
命令的效果:
>>> import psutil
>>> psutil.test()
USER PID %MEM VSZ RSS NICE STATUS START TIME CMDLINE
root 1 0.6 164.9M 11.4M sleep 18:15 01:01 /sbin/init s
root 2 0.0 0.0B 0.0B sleep 18:15 00:00 kthreadd
...
root 7896 0.0 0.0B 0.0B idle 21:55 00:00 kworker/u256
shawn 7904 1.5 49.2M 29.1M runni 21:58 00:00 python3
>>>
Windows services:获取windows的服务
>>> list(psutil.win_service_iter())
[<WindowsService(name='AeLookupSvc', display_name='Application Experience') at 38850096>,
<WindowsService(name='ALG', display_name='Application Layer Gateway Service') at 38850128>,
<WindowsService(name='APNMCP', display_name='Ask Update Service') at 38850160>,
<WindowsService(name='AppIDSvc', display_name='Application Identity') at 38850192>,
...]
>>> psutil.win_service_get('alg')
<WindowsService(name='alg', display_name='Application Layer Gateway Service') at 2325310212128>
>>> s = psutil.win_service_get('alg')
>>> s.as_dict()
{
'binpath': 'C:\\Windows\\System32\\alg.exe',
'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
'display_name': 'Application Layer Gateway Service',
'name': 'alg',
'pid': None,
'start_type': 'manual',
'status': 'stopped',
'username': 'NT AUTHORITY\\LocalService'}
'''
Author:淘小欣
blog:https://blog.taoxiaoxin.club/
script_info:检测系统硬件脚本
Edition:v0.0.1
'''
# !/usr/bin/env python
# coding:utf-8
import psutil
import datetime
import time
# 当前时间
now_time = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
print(now_time)
# 查看cpu物理个数的信息
print(u"物理CPU个数: %s" % psutil.cpu_count(logical=False))
# cpu的使用率
cpu = (str(psutil.cpu_percent(1))) + '%'
print("cup使用率: %s" % cpu)
# 查看内存信息,剩余内存.free 总共.total
# round()函数方法为返回浮点数x的四舍五入值。
free = str(round(psutil.virtual_memory().free / (1024.0 * 1024.0 * 1024.0), 2))
total = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0 * 1024.0), 2))
memory = int(psutil.virtual_memory().total - psutil.virtual_memory().free) / float(psutil.virtual_memory().total)
print("物理内存: %s G" % total)
print("剩余物理内存: %s G" % free)
print("物理内存使用率: %s %%" % int(memory * 100))
# 获取系统启动时间
print("系统启动时间: %s" % datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S"))
# 获取系统用户
users_count = len(psutil.users())
users_list = ",".join([u.name for u in psutil.users()])
print("当前有%s个用户,分别是 %s" % (users_count, users_list))
# 获取网卡信息,可以得到得到网卡属性,连接数,当前数据等信息
net = psutil.net_io_counters()
bytes_sent = '{0:.2f} Mb'.format(net.bytes_recv / 1024 / 1024)
bytes_rcvd = '{0:.2f} Mb'.format(net.bytes_sent / 1024 / 1024)
print("网卡接收数据 %s 网卡发送数据 %s" % (bytes_rcvd, bytes_sent))
# 获取磁盘数据信息
io = psutil.disk_partitions()
print('-----------------------------磁盘信息---------------------------------------')
for i in io:
try:
o = psutil.disk_usage(i.device)
print("总容量:" + str(int(o.total / (1024.0 * 1024.0 * 1024.0))) + "G")
print("已用容量:" + str(int(o.used / (1024.0 * 1024.0 * 1024.0))) + "G")
print("可用容量:" + str(int(o.free / (1024.0 * 1024.0 * 1024.0))) + "G")
except PermissionError:
continue
print('-----------------------------进程信息-------------------------------------')
# 查看系统全部进程
for pnum in psutil.pids():
p = psutil.Process(pnum)
print(
"进程名 %-20s 内存利用率 %-18s 进程状态 %-10s 创建时间 %-10s " % (p.name(), p.memory_percent(), p.status(), p.create_time()))