pustil - 获取系统信息库

Photo from Unsplash

运维工程师经常使用 Python 编写脚本程序来做监控系统运行的状态。如果自己手动使用 Python 的标准库执行系统命令来获取信息,会显得非常麻烦。既要兼容不同操作系统,又要自己处理解析信息。为了解决的痛点问题,psutil 就横空出世。它的出现无疑是运维工程师的福音。运维小伙伴通过它执行一两行代码即可实现系统监控。

1 简介

psutil 全称是 process and system utilities。psutil 是一个跨平台的应用于系统监控、分析、以及对系统进程进行一定管理的 Python 第三方库。它不仅能够轻松获取系统中正常运行的进程和系统利用率(例如 CPU、内存、磁盘、网络等)信息,还实现了跟 UNIX 系统命令行工具类似的功能。可以说是运维工作的“必备品”。

它功能强大,操作简单。这也促使很多开源项目都集成它到自己项目中,不妨有谷歌的 GRR 项目、脸书的 osquery 项目等。

github 地址:https://github.com/giampaolo/psutil

2 安装

安装 psutil 是有多种办法:通过 pip 安装,通过源码方式安装,通过下载 tar 压缩包来安装。其中通过 pip 的方式是最简单的。

pip install psutil
# 如果出现因下载失败导致安装不上的情况,建议使用代理
pip --proxy http://代理ip:端口 install psutil

3 使用

前面说到 psutil 能监听到 CPU、内存、磁盘、网络、传感器、进程等,现在跟着我来学习下。

3.1 获取 CPU 信息

1)我先获取自己电脑 CPU 的核心数,我电脑的 CPU 型号是 I5 4590。我通过搜索引擎得知该型号 CPU 是四核四线。

import psutil

psutil.cpu_count()  # 获取 CPU 的逻辑核心数,默认logical=True
psutil.cpu_count(logical=False)    # 获取 CPU 的物理核心数

>> 4
>> 4
# 这说明该 CPU 型号是真四核。

2)统计 CPU 的时间:

import psutil
psutil.cpu_times() 

>> scputimes(user=9276.365234375, system=5034.5390625, idle=96077.0703125, interrupt=181.78796863555908, dpc=298.227108001709)

cpu_times() 返回的是带有系统所有逻辑 CPU 运行时间的元组,单位是秒。返回元组的字段中有这几个常用字段:

  • user:执行用户进程的时间,Linux 系统还包括访客的时间
  • system:执行内核进程时间
  • idle:闲置时间
  • iowait(Linux 特有):等待 I/O 操作的时间
  • irp(Linux 特有):打断服务硬件的时间
  • interrupt(Windows 特有):跟 irp 字段类似
  • dpc(Windows 特有):服务延迟程序调用(DPCs)的时间

如果增加参数 percpu=Truecpu_times() 会以列表的形式输出每个逻辑 CPU 的时间。

3)获取当前 CPU 的利用率的百分比:

import psutil

psutil.cpu_percent()
>> 16.5

cpu_percent() 默认的参数是 interval=None, percpu=False。当 interval 为0或者None时,表示的是 interval 时间内的sys的利用率。当 percpu 为 False 表示所有逻辑 CPU 的使用率。

如果你想统计 15 秒中内,间隔 5 秒每个逻辑 CPU 的使用率,你可以这么做:

import psutil

for i in range(3):
    psutil.cpu_percent(interval=5, percpu=True)

>>  [9.1, 7.2, 7.2, 6.2]
>>  [5.9, 3.8, 9.0, 8.4]
>>  [12.3, 8.4, 3.4, 4.1]

4)获取 CPU 频率信息:

import psutil

psutil.cpu_freq()
>> [scpufreq(current=931.42925, min=0.0, max=3301.0)]

可知 cpu_freq() 返回的带有所有逻辑 CPU 频率的元组,包括当前、最小和最大频率。

3.2 获取内存信息

1)获取物理内存信息:

import psutil

psutil.virtual_memory()
>>  svmem(total=8509177856, 
available=1692307456, percent=80.1, used=6816870400, free=1692307456)

virtual_memory() 返回一个记载当前电脑设备中可用的物理内存信息的元组,单位是字节。从返回结果得知,当前内存总大小为 8509177856 Byte = 8 GB,可用内存(闲置内存) 1692307456 Byte = 1.6 GB`,当前内存使用率为 80.1%。值得注意的是,内存总大小不等于 Used 和 available 两者的总和

available 字段在 Linux 系统下,计算方式则不同。available = free + buffers +cached。buffers 指的是 Linux 系统下的 Buffers 内存, 表示块设备(block device)所占用的缓存页; 而 cached 指的是 Linux 系统下的 Cache 内存,顾名思义为高速缓存。

2)获取交换内存信息:

import psutil

psutil.swap_memory()
>>  sswap(total=17016451072, used=7407996928, free=9608454144, percent=43.5, sin=0, sout=0)

swap_memory() 获取的是系统的交换内存的信息,也就是我们常说的虚拟内存。前面四个字段跟物理内存含义一样。而 sin 表示从磁盘调入是 swap 的大小, sout 表示从swap调出到 disk 的大小。这两个字段在 Windows 系统下是没有意义。因此,获取结果为 0。

3.3 获取磁盘信息

1)获取磁盘分区信息:

import psutil

psutil.disk_partitions()

>>  
[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')]

disk_partitions(all=False) 返回所有挂载磁盘分区信息的列表。有点类似 Linux 的 df 命令。各个字段的含有分别为:

  • device:分区
  • mountpoint:挂载点
  • fstype:文件系统格式
  • opts:挂载参数

大部分人都对 Windows 系统的分区信息了解比较多,对 Linux 系统所知甚少。因此,我给出虚拟机 Ubuntu 系统的磁盘信息, 方便大家学习。

[sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,errors=remount-ro'),
 sdiskpart(device='/dev/sda2', mountpoint='', fstype='swap', opts='rw')]

2)获取磁盘使用率:

disk_usage() 统计参数中路径目录的磁盘使用情况。它需要传入一个路径参数;我传入的参数是 "/",意味着获取当前整个硬盘的使用率。

import psutil

psutil.disk_usage('/')

>>  sdiskusage(total=128033574912, used=81997942784, free=46035632128, percent=64.0)

3)获取磁盘 IO 信息:

import psutil

psutil.disk_io_counters()

>>  sdiskio(read_count=510749, write_count=505110, read_bytes=13353246720, write_bytes=8962015232, read_time=275, write_time=238)

disk_io_counters() 获取当前磁盘的 I/O 数据信息情况,也就是读取和写入信息。

3.4 获取网络信息

1)获取整个系统的网络信息

import psutil

psutil.disk_io_counters()

>>  snetio(bytes_sent=77587966, bytes_recv=1113555204, packets_sent=500638, packets_recv=1048467, errin=0, errout=0, dropin=0, dropout=0)

disk_io_counters() 返回整个系统所有网卡(包括有线网卡、无限网卡)的进行网络读写数据、发包数等信息。个人认为可以使用该方法来抓包。各个字段含义如下:

  • bytes_sent:发送的字节数
  • bytes_recv:收的字节数
  • packets_sent:发送到数据包的个数
  • packets_recv:接受的数据包的个数
  • errout:发送数据包错误的总数
  • dropin:接收时丢弃的数据包的总数
  • dropout:发送时丢弃的数据包的总数( OSX 和 BSD 系统总是 0 )

如果增加参数 pernic=True,disk_io_counters() 则会分别输出各个网卡的网络信息数据。

2)获取当前网络连接信息

net_connections() 的作用跟系统命令 "netstat -an" 是一样的。输出当前系统中所有类型的网络连接数据。

import psutil

psutil.net_connections()
# 数据过多,我就不打印输出结果。

3)获取网络接口信息

我们能通过 net_if_addrs() 函数来获取到各个网卡的 IP 地址、网关等信息

import psutil
psutil.net_if_addrs()

4)获取网络接口状态

net_if_stats() 获取的是各个网卡的状态信息,例如网卡是否处于激活状态、当前网速等

import psutil
psutil.net_if_addrs()

3.5 获取系统相关信息

1) 获取当前登录用户信息

import psutil

psutil.users()
>>  [suser(name='monkey', terminal=None, host='0.125.2.117', started=1515585444.0, p
id=None)]

users() 是返回当前登录用户的信息。例如用户的名称 name、运行的终端 terminal, 在 Windows 系统下就是我们常说的 CMD 窗口、登录的 IP 地址 host、登录的时长 started 以及登录的进程 pid,在 Windows 和 OpenBSD 系统中,该字段为 None。

2)获取系统启动时间

psutil.boot_time() 获取的是系统启动的时间点,而不会启动消耗时长。

3.6 获取进程信息

如果查看当前系统的所有进程信息,你可以使用 test() 方法。跟 Windows 系统下的 "tasklist" 命令作用类似。

import psutil
psutil.test()

psutil 还提供一列的方法来查看系统进程的信息。

import psutil

psutil.pids()    # 列出所有进程的PID
>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 37, 38, 40, 41, 71,
 199, 203, 218, 219, 220, 325, 327, 344, 345, 364, 417, 569, 764, 765, 817,
 1042, 1058, 1070, 1110, 1186, 1194, 1197, 1209, 1211, 1213, 1215, 1217, 1219,
 1228, 1229, 1231, 1298, 1643, 1745, 1794, 1796, 1829, 1846, 2004, 2039, 2154,
  2175]

p = psutil.Process(2154)  # 实例化一个Process对象,参数为一个进程的PID
p.name()   # 获取进程名
>> 'python'

p.exe()    # 获取进程 bin 路径, 即安装路径
>>'/usr/bin/python'

p.cwd()    # 获取进程的工作目录
>> '/root'

p.status()   # 获取进程的运行状态
>>'running'

p.create_time()    # 获取进程创建时间点
>> 1427469528.49

p.cpu_times()    # 获取进程使用 CPU 时间信息
>> pcputimes(user=0.081150144, system=0.053269812, children_user=0.0, children_system=0.0)

p.memory_info() # 获取进程使用的内存
>> pmem(rss=8310784, vms=2481725440, pfaults=3207, pageins=18)

p.open_files() # 获取进程打开的文件
>> []

p.connections() # 获取进程相关网络连接
>> []

p.num_threads() # 获取进程的线程数量
>> 1

END

作者:猴哥

公众号:极客猴

爱好读书,喜欢钻研技术,梦想成为文艺青年的 boy。

原文发布于微信公众号 - 极客猴(Geek_monkey)

原文发表时间:2018-01-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Crossin的编程教室

Python 实战(1):在网页上显示信息

上次简单介绍了 web.py。今天先来粗略解释下那个 hello world 页面的代码: import web 导入 web.py 模块。 urls = ( ...

3517
来自专栏java一日一条

40+个对初学者非常有用的PHP技巧(一)

今天我们要介绍一些关于改善和优化PHP代码的提示和技巧。请注意,这些PHP技巧适用于初学者,而不是那些已经在使用MVC框架的人。

1242
来自专栏前端杂货铺

node模块加载层级优化

模块加载痛点 大家也或多或少的了解node模块的加载机制,最为粗浅的表述就是依次从当前目录向上级查询node_modules目录,若发现依赖则加载。但是随着应用...

3758
来自专栏编程

2018 年了,你还是只会 npm install 吗?

你真的了解 npm 吗 ?重新介绍 npm 。

3.8K16
来自专栏沈唁志

ThinkPHP-PHP开发中的主流框架

8574
来自专栏安恒网络空间安全讲武堂

Python编写渗透工具学习笔记一 | 0x01 目录扫描程序

0x01web目录扫描程序 脚本利用演示 直接输入python DirScan.py会打印出使用说明信息 ? 然后扫描一下 ? 可以看到扫描出了我的服务器的这些...

4657
来自专栏java一日一条

40+个对初学者非常有用的PHP技巧(一)

今天我们要介绍一些关于改善和优化PHP代码的提示和技巧。请注意,这些PHP技巧适用于初学者,而不是那些已经在使用MVC框架的人。

923
来自专栏代码世界

Python之IO模型

IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步、异步、阻塞、非阻塞     同步(synchronous) IO和异步(asynchronous...

44111
来自专栏我是攻城师

使用Java Rest Client操作Elasticsearch

8415
来自专栏Golang语言社区

如何优化服务器的性能

一、通常服务器的性能会卡在三个地方: cpu 网络IO 磁盘IO 二、在优化性能的时候,首先要判断性能的瓶颈在上述的哪个地方。然后对症下药,按照下面的方法来优化...

5356

扫码关注云+社区

领取腾讯云代金券