Python之psutil

用Python来编写脚本简化日常的运维工作。在Python中获取系统信息的好办法是使用psutil这个第三方模块,psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。


获取CPU信息

函数解析

函数 描述
psutil.cpu_count() cpu_count(,[logical]):默认返回逻辑CPU的个数,当设置logical的参数为False时,返回物理CPU的个数。
psutil.cpu_percent() cpu_percent(,[percpu],[interval]):返回CPU的利用率,percpu为True时显示所有物理核心的利用率,interval不为0时,则阻塞时显示interval执行的时间内的平均利用率
psutil.cpu_times() cpu_times(,[percpu]):以命名元组(namedtuple)的形式返回cpu的时间花费,percpu=True表示获取每个CPU的时间花费
psutil.cpu_times_percent() cpu_times_percent(,[percpu]):功能和cpu_times大致相同,看字面意思就能知道,该函数返回的是耗时比例。
psutil.cpu_stats() cpu_stats()以命名元组的形式返回CPU的统计信息,包括上下文切换,中断,软中断和系统调用次数。
psutil.cpu_freq() cpu_freq([percpu]):返回cpu频率

代码展示

import psutil
# 查看cpu个数
psutil.cpu_count() # 逻辑CPU
psutil.cpu_count(logical=False) # 物理CPU
# 查看cpu利用率
psutil.cpu_percent()
psutil.cpu_percent(percpu=True)
 psutil.cpu_percent(1)
# 查看cpu时间花费
psutil.cpu_times()
psutil.cpu_times(percpu=True)
psutil.cpu_times().user
psutil.cpu_times().iowait

获取内存信息

函数解释

函数 描述
psutil.virtual_memory() 以命名元组的形式返回内存使用情况,包括总内存,可用内存,内存利用率,buffer和cache等,单位为字节。
psutil.swap_memory() 以命名元组的形式返回swap/memory使用情况,包含swap中页的换入和换出

代码展示

import psutil
psutil.virtual_memory()
psutil.virtual_memory().total
psutil.virtual_memory().used
psutil.virtual_memory().free
psutil.swap_memory()

补充内容:单位转换

import psutil
def bytes2human(n):
     symbols = ('K','M','G','T','P','E','Z','Y')
     prefix = {}
     for i,s in enumerate(symbols):
         prefix[s] = 1 << (i + 1) * 10
     for s in reversed(symbols):
         if n >= prefix[s]:
             value = float(n) / prefix[s]
             return '%.1f%s' % (value,s)
     return '%sB' % n
print(bytes2human(psutil.virtual_memory().total))

获取硬盘信息

函数解释

函数 描述
psutil.disk_io_counters() disk_io_counters([perdisk]):以命名元组的形式返回磁盘io统计信息(汇总的),包括读、写的次数,读、写的字节数等。当perdisk的值为True,则分别列出单个磁盘的统计信息(字典:key为磁盘名称,value为统计的namedtuple)。
psutil.disk_partitions() disk_partitions([all=False]):以命名元组的形式返回所有已挂载的磁盘,包含磁盘名称,挂载点,文件系统类型等信息。当all等于True时,返回包含/proc等特殊文件系统的挂载信息
psutil.disk_usage() disk_usage(path):以命名元组的形式返回path所在磁盘的使用情况,包括磁盘的容量、已经使用的磁盘容量、磁盘的空间利用率等。

代码展示

import psutil
# 查看所有已挂在的磁盘(磁盘分区信息)
psutil.disk_partitions()
# 使用列表表达式查询指定挂载点信息
[device for device in psutil.disk_partitions() if device.mountpoint == '/']
# 查看磁盘使用情况
psutil.disk_usage('/')
# 查看磁盘io统计汇总
psutil.disk_io_counters()
# 分别列出单个磁盘的统计信息
psutil.disk_io_counters(perdisk=True)

获取网络信息

函数解释

函数 描述
psutil.net_io_counter([pernic]) 以命名元组的形式返回当前系统中每块网卡的网络io统计信息,包括收发字节数,收发包的数量、出错的情况和删包情况。当pernic为True时,则列出所有网卡的统计信息。
psutil.net_connections([kind]) 以列表的形式返回每个网络连接的详细信息(namedtuple)。命名元组包含fd, family, type, laddr, raddr, status, pid等信息。kind表示过滤的连接类型,支持的值如下:(默认为inet)
psutil.net_if_addrs() 以字典的形式返回网卡的配置信息,包括IP地址和mac地址、子网掩码和广播地址。
psutil.net_if_stats() 返回网卡的详细信息,包括是否启动、通信类型、传输速度与mtu。
psutil.users() 以命名元组的方式返回当前登陆用户的信息,包括用户名,登陆时间,终端,与主机信息
psutil.boot_time() 以时间戳的形式返回系统的启动时间

代码展示

import psutil
# 查看网卡信息统计(获取网络读写字节/包的个数)
psutil.net_io_counters()
# 获取单个网卡的io信息
psutil.net_io_counters(pernic=True)
# 查看网卡配置信息
psutil.net_if_addrs()
# 获取网络接口状态
psutil.net_if_stats()
# 查看当前登录用户信息
psutil.users()
# 要获取当前网络连接信息
psutil.net_connections() #可能会得到一个AccessDenied错误,原因是psutil获取信息也是要走系统接口,而获取网络连接信息需要root权限,这种情况下,可以退出Python交互环境,用sudo重新启动
# 以linux时间格式返回,可以使用时间戳转换
psutil.boot_time()    
# 转换成自然时间格式
datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H: %M: %S")

获取进程信息

函数解释

函数 描述
psutil.pids() 以列表的形式返回当前正在运行的进程
psutil.pid_exists(1) 判断给点定的pid是否存在
psutil.process_iter() 迭代当前正在运行的进程,返回的是每个进程的Process对象
psutil.Process() 对进程进行封装,可以使用该类的方法获取进行的详细信息,或者给进程发送信号。

进程相关信息的方法

  • children:子进程列表
  • cmdline:获取启动进程的命令行参数
  • connectios:进程相关网络连接
  • cpu_affinity:get进程cpu亲和度,如果要设置cpu亲和度,将cpu号作为参考就好
  • cpu_times:进程的cpu时间信息,包括user,system两个cpu信息
  • create_time:获取进程的创建时间(时间戳格式)
  • cwd:进程的工作目录绝对路径
  • exe:进程的bin路径
  • environ:进程环境变量
  • gids:进程的gid信息
  • io_counters:进程的IO信息,包括读写IO数字及参数
  • is_running:判断进程是否正在运行
  • kill:发送SIGKILL信号结束进程
  • memory_info:进程内存rss,vms信息
  • memory_percent:进程内存利用率
  • name:获取进程的名称
  • num_fds:进程打开的文件个数
  • num_threads:进程开启的线程数
  • open_files:进程打开的文件
  • ppid:父进程ID
  • parent:父进程
  • send_signal:给进程发送信号,类似与os.kill等
  • status:进程状态
  • terminal:进程终端
  • terminate:发送SIGTEAM信号结束进程
  • uids:进程uid信息
  • username:进程用户名

代码展示

import psutil
# 以列表形式查看正在运行的进程
psutil.pids()
# 查看进程运行状态,以布尔形式显示
psutil.pid_exists(1)
# 迭代当前正在运行进程,查看列表中前三个实例的信息
list(psutil.process_iter())[:3]
# 通过进程号实例化对象
process = psutil.Process(1)
print(process)
psutil.Process(pid=1, name='systemd', started='16:19:47')
# 获取进程的名称
process.name()
process.create_time()
process.num_fds()
process.num_threads()
# Process方法
p=psutil.Process(1252)
p.name()      #进程名
p.exe()         #进程的bin路径
p.cwd()        #进程的工作目录绝对路径
p.status()     #进程状态
p.cmdline()  #进程启动的命令行
p.create_time()  #进程创建时间
p.ppid() # 父进程ID
p.parent() # 父进程
p.children() # 子进程列表
p.uids()      #进程uid信息
p.gids()      #进程的gid信息
p.cpu_times()    #进程的cpu时间信息,包括user,system两个cpu信息
p.cpu_affinity()  #get进程cpu亲和度,如果要设置cpu亲和度,将cpu号作为参考就好
p.memory_percent()  #进程内存利用率
p.memory_info()    #进程内存rss,vms信息
p.io_counters()    #进程的IO信息,包括读写IO数字及参数
p.connectios()    #返回进程列表
p.num_threads()  #进程开启的线程数
# psutil的Popen方法启动应用程序,可以跟踪程序的相关信息
from subprocess import PIPE
p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"],stdout=PIPE)
p.name()
p.username()

实战脚本

# 查看系统硬件脚本
#!/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(u"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(u"物理内存: %s G" % total)
print(u"剩余物理内存: %s G" % free)
print(u"物理内存使用率: %s %%" % int(memory * 100))
# 系统启动时间
print(u"系统启动时间: %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(u"当前有%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(u"网卡接收流量 %s 网卡发送流量 %s" % (bytes_rcvd, bytes_sent))
io = psutil.disk_partitions()

print('-----------------------------磁盘信息---------------------------------------')

print("系统磁盘信息:" + str(io))

for i in io:
    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")

print('-----------------------------进程信息-------------------------------------')
# 查看系统全部进程
for pnum in psutil.pids():
    p = psutil.Process(pnum)
    print(u"进程名 %-20s  内存利用率 %-18s 进程状态 %-10s 创建时间 %-10s " \
    % (p.name(), p.memory_percent(), p.status(), p.create_time()))