作者:四喜Clion
链接:https://www.zhihu.com/question/399160308/answer/2603725164
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1.模块简介

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等。目前支持32位和64位的Linux、 Windows、OS X、FreeBSD和Sun Solaris等操作系统,支持从2.4到3.4的Python版本。

通常我们获取操作系统信息往往采用编写shell来实现,如获取当前物理内存总大小及已使用大小,shell命令如下:

[root@prometheus01 ~]# free -b|grep Mem|awk '{print $2}'
4125114368
[root@prometheus01 ~]# free -b|grep Mem|awk '{print $3}'
146026496

相比较而言,使用psutil库实现则更加简单明了。psutil大小单位一般都采用字节,如下:

[root@prometheus01 ~]# python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import psutil
>>> mem=psutil.virtual_memory()
>>> mem.total,mem.used
(4125114368, 200011776)

2.获取系统性能信息

采集系统的基本性能信息包括CPU、内存、磁盘、网络等,可以完整描述当前系统的运行状态及质量。psutil模块已经封装了这些方法,用户可以根据自身的应用场景,调用相应的方法来满足需求,非常简单实用。

2.1CPU信息Linux操作系统的CPU利用率有以下几个部分

  • User Time,执行用户进程的时间百分比
  • System Time,执行内核进程和中断的时间百分比
  • Wait IO,由于IO等待而使CPU处于idle(空闲)状态的时间百分比;
  • Idle,CPU处于idle状态的时间百分比。
  • 我们使用Python的psutil.cpu_times()方法可以非常简单地得到这些信息,同时也可以获取CPU的硬件相关信息,比如CPU的物理个数与逻辑个数,具体见下面的操作例子

获取全部cpu信息

>>> psutil.cpu_times()
scputimes(user=966.81, nice=4.77, system=3096.13, idle=5485146.9, iowait=79.52, irq=0.0, softirq=132.47, steal=0.0, guest=0.0, guest_nice=0.0)
  • 获取cpu某个指标的cpu信息
# cpu用户时间百分比
>>> psutil.cpu_times().user   
966.83
# 逻辑cpu数量
>>> psutil.cpu_count()   
2
# 物理cpu的数量
>>> psutil.cpu_count(logical=False)  
1

2.2内存信息

Linux系统的内存利用率信息涉及total(内存总数)、used(已使 用的内存数)、free(空闲内存数)、buffers(缓冲使用数)、 cache(缓存使用数)、swap(交换分区使用数)等,分别使用 psutil.virtual_memory()与psutil.swap_memory()方法获取这些信 息,具体见下面的操作例子:

获取全部内存信息:

>>> mem=psutil.virtual_memory()
>>> mem
svmem(total=4125114368, available=3599085568, percent=12.8, used=201023488, free=210567168, active=1976868864, inactive=1640312832, buffers=3289088, cached=3710234624, shared=37261312, slab=203649024)

获取内存某个指标信息:

# 总内存
>>> mem.total    
4125114368
# 空闲内存
>>> mem.free
210567168
# swap分区信息
>>> psutil.swap_memory()
sswap(total=2147479552, used=270336, free=2147209216, percent=0.0, sin=0, sout=28672)

2.3磁盘信息

在系统的所有磁盘信息中,我们更加关注磁盘的利用率及IO信 息,其中磁盘利用率使用psutil.disk_usage方法获取。磁盘IO信息包括 read_count(读IO数)、write_count(写IO数)、read_bytes(IO读字节 数)、write_bytes(IO写字节数)、read_time(磁盘读时间)、 write_time(磁盘写时间)等。这些IO信息可以使用 psutil.disk_io_counters()获取,具体见下面的操作例子:

# 获取磁盘的挂载信息
>>> psutil.disk_partitions()
[sdiskpart(device='/dev/mapper/centos-root', mountpoint='/', fstype='xfs', opts='rw,relatime,attr2,inode64,noquota'), sdiskpart(device='/dev/sda1', mountpoint='/boot', fstype='xfs', opts='rw,relatime,attr2,inode64,noquota')]
# 获取根目录的磁盘使用情况
>>> psutil.disk_usage('/')
sdiskusage(total=104961515520, used=4649857024, free=100311658496, percent=4.4)
# 获取磁盘整体io的信息
>>> psutil.disk_io_counters()
sdiskio(read_count=15805, write_count=330268, read_bytes=513860096, write_bytes=11843909632, read_time=10913, write_time=357121, read_merged_count=12, write_merged_count=14355, busy_time=141680)
# 更细粒度的获取每块盘的磁盘io信息
>>> psutil.disk_io_counters(perdisk=True)
{'sda': sdiskio(read_count=8896, write_count=159022, read_bytes=260540416, write_bytes=5923184128, read_time=5603, write_time=165861, read_merged_count=12, write_merged_count=14356, busy_time=71005), 'sda1': sdiskio(read_count=1868, write_count=2121, read_bytes=6856192, write_bytes=2342912, read_time=323, write_time=205, read_merged_count=0, write_merged_count=0, busy_time=513), 'sda2': sdiskio(read_count=6998, write_count=156901, read_bytes=252611072, write_bytes=5920841216, read_time=5272, write_time=165656, read_merged_count=12, write_merged_count=14356, busy_time=70500), 'sr0': sdiskio(read_count=36, write_count=0, read_bytes=2105344, write_bytes=0, read_time=61, write_time=0, read_merged_count=0, write_merged_count=0, busy_time=46), 'dm-0': sdiskio(read_count=6740, write_count=171250, read_bytes=247876096, write_bytes=5920812544, read_time=5221, write_time=191152, read_merged_count=0, write_merged_count=0, busy_time=70562), 'dm-1': sdiskio(read_count=133, write_count=7, read_bytes=3338240, write_bytes=28672, read_time=28, write_time=117, read_merged_count=0, write_merged_count=0, busy_time=69)}

2.4网络信息

系统的网络信息与磁盘IO类似,涉及几个关键点,包括 bytes_sent(发送字节数)、bytes_recv(接收字节数)、 packets_sent(发送数据包数)、packets_recv(接收数据包数)等。这些网络信息使用psutil.net_io_counters()方法获取,具体见下面的操作例子:

# 使用psutil.net_io_counters获取网络总IO信息,默认pernic为False
>>> psutil.net_io_counters()
snetio(bytes_sent=81534167, bytes_recv=1700214232, packets_sent=745802, packets_recv=1468433, errin=0, errout=0, dropin=0, dropout=0)
# pernic=True获取每个网络接口的网络io信息
>>> psutil.net_io_counters(pernic=True)
{'lo': snetio(bytes_sent=50811, bytes_recv=50811, packets_sent=616, packets_recv=616, errin=0, errout=0, dropin=0, dropout=0), 'ens33': snetio(bytes_sent=81489782, bytes_recv=1700167321, packets_sent=745217, packets_recv=1467861, errin=0, errout=0, dropin=0, dropout=0)}

2.5其他系统信息

除了前面介绍的几个获取系统基本信息的方法,psutil模块还支持获取用户登录,开机信息等信息,具体见下面的操作例子:

>>> psutil.users()
[suser(name='root', terminal='tty1', host='', started=1645193344.0, pid=660), suser(name='root', terminal='pts/0', host='192.168.172.1', started=1648517248.0, pid=95380), suser(name='root', terminal='pts/1', host='192.168.172.1', started=1648523520.0, pid=95596)]
>>> import psutil,datetime
# 系统开机时间,以时间戳的形式表示
>>> psutil.boot_time()
1645772186.0

# 格式化转换为自然时间
>>> datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
'2022-02-25 14:56:26'

2.6系统进程管理方法

获得当前系统的进程信息,可以让运维人员得知应用程序的运行状态,包括进程的启动时间、查看或设置CPU亲和度、内存使用率、IO信息、socket连接、线程数等,这些信息可以呈现出指定进程是否存活、资源利用情况,为开发人员的代码优化、问题定位提供很好的数据参考。
1.进程信息 psutil模块在获取进程信息方面也提供了很好的支持,包括使用 psutil.pids()方法获取所有进程PID,使用psutil.Process()方法获取单个进程的名称、路径、状态、系统资源利用率等信息,具体见下面的操作例子:

>>> import psutil
# 列出所有进程PID
>>> psutil.pids()
[1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 33, 34, 35, 36, 44, 46, 47, 48, 50, 63, 97, 274, 275, 276, 284, 285, 286, 287, 288, 289, 290, 291, 368, 369, 378, 379, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 473, 494, 497, 520, 585, 586, 588, 590, 591, 594, 595, 597, 614, 637, 638, 641, 642, 648, 649, 660, 821, 891, 892, 893, 894, 1017, 1027, 1156, 12247, 20492, 24907, 30475, 33111, 90329, 94520, 94729, 95378, 95380, 95552, 95559, 95596, 95630, 95702, 95708, 95709, 95728]
# 实例化一个Process对象,参数为一进程PID
>>> p=psutil.Process(95378)
# 进程名
>>> p.name()
'sshd'
# 进程执行路径
>>> p.exe()
'/usr/sbin/sshd'
# 进程工作目录绝对路径
>>> p.cwd()
'/'
# 进程状态
>>> p.status()
'sleeping'
# 进程创建时间,时间戳格式
>>> p.create_time()
1648517277.12
# 进程uid信息
>>> p.uids()
puids(real=0, effective=0, saved=0)
# 进程gid信息
>>> p.gids()
pgids(real=0, effective=0, saved=0)
# 进程CPU时间信息,包括user,system两个cpu时间
>>> p.cpu_times()
pcputimes(user=0.04, system=0.64, children_user=0.0, children_system=0.0, iowait=0.0)
# 进程内存利用率
>>> p.memory_percent()
0.1517215631292771
# 进程IO信息,包括读写IO数及字节数
>>> p.io_counters()
pio(read_count=3960, write_count=3544, read_bytes=1032192, write_bytes=0, read_chars=960672, write_chars=358255)
# 返回打开进程socket的namedutples列表,包括fs,family,laddr
>>> p.connections()
[pconn(fd=3, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.172.41', port=22), raddr=addr(ip='192.168.172.1', port=62362), status='ESTABLISHED')]
# 进程开启的线程数
>>> p.num_threads()
1
psutil提供的popen类的作用是获取用户启动的应用程序进程信息,以便跟踪程序进程的运行状态。具体实现方法如下:

>>> import psutil
>>> from subprocess import PIPE
>>> p=psutil.Popen(["/usr/bin/python","-c" "print('hello')"],stdout=PIPE)
>>> p.name()
'python3'
>>> p.username()
'root'
>>> p.communicate()
(b'hello\n', None)
# 得到进程运行的cpu时间
>>> p.cpu_times()
pcputimes(user=0.0, system=0.0, children_user=0.0, children_system=0.0, iowait=0.0)

折叠

psutil提供的popen类的作用是获取用户启动的应用程序进程信息,以便跟踪程序进程的运行状态。具体实现方法如下:

>>> import psutil
>>> from subprocess import PIPE
>>> p=psutil.Popen(["/usr/bin/python","-c" "print('hello')"],stdout=PIPE)
>>> p.name()
'python3'
>>> p.username()
'root'
>>> p.communicate()
(b'hello\n', None)
# 得到进程运行的cpu时间
>>> p.cpu_times()
pcputimes(user=0.0, system=0.0, children_user=0.0, children_system=0.0, iowait=0.0)

3.关于psutil模块更多用法

>>> dir(psutil)
['AF_LINK', 'AIX', 'AccessDenied', 'BSD', 'CONN_CLOSE', 'CONN_CLOSE_WAIT', 'CONN_CLOSING', 'CONN_ESTABLISHED', 'CONN_FIN_WAIT1', 'CONN_FIN_WAIT2', 'CONN_LAST_ACK', 'CONN_LISTEN', 'CONN_NONE', 'CONN_SYN_RECV', 'CONN_SYN_SENT', 'CONN_TIME_WAIT', 'Error', 'FREEBSD', 'IOPRIO_CLASS_BE', 'IOPRIO_CLASS_IDLE', 'IOPRIO_CLASS_NONE', 'IOPRIO_CLASS_RT', 'LINUX', 'MACOS', 'NETBSD', 'NIC_DUPLEX_FULL', 'NIC_DUPLEX_HALF', 'NIC_DUPLEX_UNKNOWN', 'NoSuchProcess', 'OPENBSD', 'OSX', 'POSIX', 'POWER_TIME_UNKNOWN', 'POWER_TIME_UNLIMITED', 'PROCFS_PATH', 'PermissionError', 'Popen', 'Process', 'ProcessLookupError', 'RLIMIT_AS', 'RLIMIT_CORE', 'RLIMIT_CPU', 'RLIMIT_DATA', 'RLIMIT_FSIZE', 'RLIMIT_LOCKS', 'RLIMIT_MEMLOCK', 'RLIMIT_MSGQUEUE', 'RLIMIT_NICE', 'RLIMIT_NOFILE', 'RLIMIT_NPROC', 'RLIMIT_RSS', 'RLIMIT_RTPRIO', 'RLIMIT_RTTIME', 'RLIMIT_SIGPENDING', 'RLIMIT_STACK', 'RLIM_INFINITY', 'STATUS_DEAD', 'STATUS_DISK_SLEEP', 'STATUS_IDLE', 'STATUS_LOCKED', 'STATUS_PARKED', 'STATUS_RUNNING', 'STATUS_SLEEPING', 'STATUS_STOPPED', 'STATUS_TRACING_STOP', 'STATUS_WAITING', 'STATUS_WAKING', 'STATUS_ZOMBIE', 'SUNOS', 'TimeoutExpired', 'WINDOWS', 'ZombieProcess', '_LOWEST_PID', '_PY3', '_TOTAL_PHYMEM', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_as_dict_attrnames', '_assert_pid_not_reused', '_common', '_compat', '_cpu_busy_time', '_cpu_times_deltas', '_cpu_tot_time', '_last_cpu_times', '_last_cpu_times_2', '_last_per_cpu_times', '_last_per_cpu_times_2', '_lock', '_pmap', '_ppid_map', '_pprint_secs', '_pslinux', '_psplatform', '_psposix', '_psutil_linux', '_psutil_posix', '_timer', '_wrap_numbers', 'boot_time', 'collections', 'contextlib', 'cpu_count', 'cpu_freq', 'cpu_percent', 'cpu_stats', 'cpu_times', 'cpu_times_percent', 'datetime', 'disk_io_counters', 'disk_partitions', 'disk_usage', 'functools', 'getloadavg', 'long', 'net_connections', 'net_if_addrs', 'net_if_stats', 'net_io_counters', 'os', 'pid_exists', 'pids', 'process_iter', 'pwd', 'sensors_battery', 'sensors_fans', 'sensors_temperatures', 'signal', 'subprocess', 'swap_memory', 'sys', 'test', 'threading', 'time', 'users', 'version_info', 'virtual_memory', 'wait_procs']
 

psutil官网:https://psutil.readthedocs.io/en/latest/
psuti的git:https://github.com/giampaolo/psutil

对python感兴趣的小伙们,这里准备了python加油站:

python基础入门15天,不长不短适合小白,liunx都是0基础讲的,很多不好理解的地方都用了各种形象的例子。

总的来说这个教程,很适合刚入门没有什么基础的伙伴学,有其他语言基础的伙伴可以两倍速快速刷,效率很高,时间上可以这样分配,用15天去学

  • 1-3 天内容为Linux基础命令
  • 4-13 天内容为Python基础教程
  • 14-15 天内容为 飞机大战项目演练

入门后还想多学,这些Python好课可以继续:

今天解决不了的事情

别着急

发表评论

邮箱地址不会被公开。 必填项已用*标注