python系统监测库-psutil完整指南

psutil 系统监控与进程管理库完全指南

psutil(Process and System Utilities)是一款 跨平台、轻量级、功能强大 的 Python 系统监控与进程管理库。核心目标是通过 统一 API 简化系统资源(CPU、内存、磁盘、网络等)和进程的监控、查询与控制,无需依赖 topnetstatdf 等系统原生命令,大幅降低跨平台系统级工具的开发成本。


一、CPU 监控

核心功能

获取 CPU 核心数、使用率、时间统计(用户态/系统态耗时等)信息,支持全局/单核心监控。

关键函数与参数

函数 功能描述
psutil.cpu_times() 返回 CPU 时间统计(user/系统/空闲等耗时)
psutil.cpu_count() 返回 CPU 核心数(默认逻辑核心,logical=False 返回复物理核心)
psutil.cpu_percent() 返回 CPU 使用率(interval:采样时间/秒;percpu=True:返回单核心使用率)

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
import psutil

# 1. CPU 时间统计(user=用户态耗时、system=系统态耗时、idle=空闲耗时等)
print("CPU 时间统计:", psutil.cpu_times())

# 2. 核心数查询
print("逻辑核心数:", psutil.cpu_count()) # 含超线程的逻辑核心
print("物理核心数:", psutil.cpu_count(logical=False)) # 实际物理核心

# 3. 使用率查询(interval=1 表示采样1秒后返回结果,避免瞬时值)
print("CPU 总使用率(1秒采样):", psutil.cpu_percent(interval=1))
print("各逻辑核心使用率(1秒采样):", psutil.cpu_percent(interval=1, percpu=True))

运行效果

CPU监控输出效果


二、内存信息监控

核心功能

分别获取 物理内存(RAM)交换内存(Swap) 的总量、使用率、可用量等信息,支持字节单位人性化转换。

2.1 物理内存(psutil.virtual_memory()

返回 svmem 类型命名元组,核心字段如下(单位:字节,percent 为百分比):

字段名 含义 跨平台支持
total 物理内存总量 全平台
available 可用内存(最关键字段,含空闲+可回收缓存) 全平台
used 已用内存(total - available 全平台
free 完全空闲内存 全平台
percent 内存使用率(used / total * 100 全平台
buffers 系统缓冲区(磁盘读写缓存) Linux/macOS 特有
cached 页缓存(文件内容缓存) Linux/macOS 特有

2.2 交换内存(psutil.swap_memory()

返回 sswap 类型命名元组,核心字段如下:

字段名 含义 单位
total 交换内存总量(虚拟内存) 字节
used 已用交换内存 字节
free 空闲交换内存 字节
percent 交换内存使用率 %
sin 从磁盘交换到内存的总字节数(swap in) 字节
sout 从内存交换到磁盘的总字节数(swap out) 字节

示例代码(含字节单位转换工具)

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
33
34
35
36
37
38
39
import psutil

def bytes_to_human(n: int, unit_base: int = 1024) -> str:
"""字节单位转换为人类可读格式(如 B→KB→MB→GB)"""
if n < 0:
return "0.00 B"
units = ["B", "KB", "MB", "GB", "TB"]
index = 0
while n >= unit_base and index < len(units) - 1:
n /= unit_base
index += 1
return f"{n:.2f} {units[index]}"

# ---------------------- 物理内存信息 ----------------------
print("=== 物理内存(virtual_memory)===")
virtual_mem = psutil.virtual_memory()
virtual_mem_human = {
"总量": bytes_to_human(virtual_mem.total),
"可用": bytes_to_human(virtual_mem.available),
"已用": bytes_to_human(virtual_mem.used),
"空闲": bytes_to_human(virtual_mem.free),
"使用率": f"{virtual_mem.percent}%",
}
for key, value in virtual_mem_human.items():
print(f"{key:8s}: {value}")

# ---------------------- 交换内存信息 ----------------------
print("\n=== 交换内存(swap_memory)===")
swap_mem = psutil.swap_memory()
swap_mem_human = {
"总量": bytes_to_human(swap_mem.total),
"已用": bytes_to_human(swap_mem.used),
"空闲": bytes_to_human(swap_mem.free),
"使用率": f"{swap_mem.percent}%",
"从磁盘交换入内存": bytes_to_human(swap_mem.sin),
"从内存交换到磁盘": bytes_to_human(swap_mem.sout)
}
for key, value in swap_mem_human.items():
print(f"{key:12s}: {value}")

运行效果

  • 物理内存输出:物理内存转换展示
  • 交换内存输出:交换内存输出效果

三、磁盘信息监控

核心功能

获取磁盘分区信息、使用率、IO 读写统计(次数/字节数/耗时),支持全局汇总与单磁盘细分。

关键函数说明

函数 功能描述 返回类型
disk_partitions(all=False) 获取磁盘分区列表(all=False 仅显示物理分区) 命名元组列表
disk_usage(path) 获取指定挂载点的磁盘使用率 sdiskusage 命名元组
disk_io_counters(perdisk=False) 获取磁盘 IO 统计(perdisk=True 返回单磁盘数据) 命名元组/字典

字段详情

1. 磁盘分区字段(disk_partitions

字段名 含义 类型
device 磁盘设备路径(Windows:C:\\;Linux:/dev/sda1 字符串
mountpoint 分区挂载点(Windows:C:\;Linux:/ 字符串
fstype 文件系统类型(NTFSext4APFS 字符串
opts 挂载选项(Windows 通常为 rw,fixed;Linux 如 rw,noatime 字符串

2. 磁盘 IO 统计字段(disk_io_counters

字段名 含义 单位
read_count 读取总次数 次数
write_count 写入总次数 次数
read_bytes 读取总字节数 字节
write_bytes 写入总字节数 字节
read_time 读取总时间(Linux/macOS:毫秒;Windows:100纳秒,需转换) 毫秒/100纳秒
write_time 写入总时间(同 read_time 同上
busy_time 磁盘忙碌总时间 毫秒(仅 Linux 支持)

示例代码

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import psutil
import platform

# 复用之前定义的字节转换工具函数
def bytes_to_human(n: int, unit_base: int = 1024) -> str:
if n < 0:
return "0.00 B"
units = ["B", "KB", "MB", "GB", "TB"]
index = 0
while n >= unit_base and index < len(units) - 1:
n /= unit_base
index += 1
return f"{n:.2f} {units[index]}"

def windows_time_convert(n: int) -> str:
"""Windows 磁盘时间单位转换(100纳秒 → 毫秒)"""
if platform.system() == "Windows":
ms = n * 0.0001
return f"{ms:.2f} 毫秒"
else:
return f"{n:.2f} 毫秒"

# ---------------------- 1. 磁盘分区信息 ----------------------
print("=== 1. 磁盘分区信息 ===")
partitions = psutil.disk_partitions(all=False) # all=False:仅显示物理分区
for idx, part in enumerate(partitions, 1):
print(f"\n分区 {idx}:")
print(f" 设备路径:{part.device}")
print(f" 挂载点:{part.mountpoint}")
print(f" 文件系统:{part.fstype}")
print(f" 挂载选项:{part.opts}")

# ---------------------- 2. 磁盘使用率 ----------------------
print("\n\n=== 2. 磁盘使用率(按挂载点)===")
# 跨平台适配:Windows 默认查询 C 盘,Linux/macOS 默认查询根目录
target_path = "C:" if platform.system() == "Windows" else "/"
disk_usage = psutil.disk_usage(target_path)
disk_usage_human = {
"挂载点": target_path,
"总容量": bytes_to_human(disk_usage.total),
"已用容量": bytes_to_human(disk_usage.used),
"空闲容量": bytes_to_human(disk_usage.free),
"使用率": f"{disk_usage.percent:.2f}%"
}
for key, value in disk_usage_human.items():
print(f" {key:8s}: {value}")

# ---------------------- 3. 磁盘 IO 统计(全局) ----------------------
print("\n\n=== 3. 磁盘 IO 统计(全局汇总)===")
disk_io = psutil.disk_io_counters(perdisk=False)
disk_io_human = {
"读取次数": disk_io.read_count,
"写入次数": disk_io.write_count,
"读取总字节": bytes_to_human(disk_io.read_bytes),
"写入总字节": bytes_to_human(disk_io.write_bytes),
"读取总时间": windows_time_convert(disk_io.read_time),
"写入总时间": windows_time_convert(disk_io.write_time),
"合并读取次数": disk_io.read_merged_count,
"合并写入次数": disk_io.write_merged_count
}
# 仅 Linux 显示忙碌时间
if hasattr(disk_io, "busy_time") and disk_io.busy_time > 0:
disk_io_human["磁盘忙碌时间"] = f"{disk_io.busy_time:.2f} 毫秒"

for key, value in disk_io_human.items():
print(f" {key:12s}: {value}")

# ---------------------- 4. 单个磁盘 IO 统计(可选) ----------------------
print("\n\n=== 4. 单个磁盘 IO 统计 ===")
disk_io_per_disk = psutil.disk_io_counters(perdisk=True)
for disk_name, io_data in disk_io_per_disk.items():
print(f"\n 磁盘 {disk_name}:")
print(f" 读取字节:{bytes_to_human(io_data.read_bytes)}")
print(f" 写入字节:{bytes_to_human(io_data.write_bytes)}")
print(f" 读取次数:{io_data.read_count}")
print(f" 写入次数:{io_data.write_count}")

运行效果

磁盘信息监控输出


四、网络信息监控

核心功能

获取网络 IO 统计(收发字节/包数)、网卡地址(IPv4/IPv6/MAC)、网卡状态(启用/速率/双工模式)。

关键函数说明

函数 功能描述 返回类型
net_io_counters(pernic=False) 网络 IO 统计(pernic=True 返回单网卡数据) 命名元组/字典
net_if_addrs() 获取网卡地址信息(IPv4/IPv6/MAC) 字典(key=网卡名)
net_if_stats() 获取网卡状态(启用/速率/MTU) 字典(key=网卡名)

字段详情

1. 网络 IO 统计字段(net_io_counters

字段名 含义 单位
bytes_recv 接收总字节数 字节
bytes_sent 发送总字节数 字节
packets_recv 接收总数据包数 次数
packets_sent 发送总数据包数 次数
errin 接收错误包数 次数
errout 发送错误包数 次数
dropin 接收丢弃包数 次数
dropout 发送丢弃包数 次数

2. 网卡地址字段(net_if_addrs

字段名 含义 类型
family 地址族(AF_INET=IPv4AF_INET6=IPv6AF_LINK=MAC 枚举值
address IP 地址/MAC 地址 字符串
netmask 子网掩码(IPv4/IPv6) 字符串
broadcast 广播地址(仅 IPv4 支持) 字符串

3. 网卡状态字段(net_if_stats

字段名 含义 类型/单位
isup 网卡是否启用 布尔值
duplex 双工模式(0=未知1=半双工2=全双工 整数
speed 网卡速率(0=未知 Mbps
mtu 最大传输单元 字节

示例代码

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import psutil
import socket
import platform

# 复用字节转换工具函数
def bytes_to_human(n: int, unit_base: int = 1024) -> str:
if n < 0:
return "0.00 B"
units = ["B", "KB", "MB", "GB", "TB"]
index = 0
while n >= unit_base and index < len(units) - 1:
n /= unit_base
index += 1
return f"{n:.2f} {units[index]}"

def family_to_name(family: int) -> str:
"""地址族枚举值转中文(AF_INET→IPv4、AF_INET6→IPv6、AF_LINK→MAC)"""
family_map = {
socket.AF_INET: "IPv4",
socket.AF_INET6: "IPv6",
psutil.AF_LINK: "MAC"
}
return family_map.get(family, f"未知({family})")

def duplex_to_name(duplex: int) -> str:
"""双工模式转中文(0→未知、1→半双工、2→全双工)"""
duplex_map = {0: "未知", 1: "半双工", 2: "全双工"}
return duplex_map.get(duplex, "未知")

# ---------------------- 1. 全局网络 IO 统计 ----------------------
print("=== 1. 全局网络 IO 统计 ===")
net_io_global = psutil.net_io_counters()
net_io_global_human = {
"接收总字节": bytes_to_human(net_io_global.bytes_recv),
"发送总字节": bytes_to_human(net_io_global.bytes_sent),
"接收数据包数": net_io_global.packets_recv,
"发送数据包数": net_io_global.packets_sent,
"接收错误包数": net_io_global.errin,
"发送错误包数": net_io_global.errout,
"接收丢弃包数": net_io_global.dropin,
"发送丢弃包数": net_io_global.dropout
}
for key, value in net_io_global_human.items():
print(f" {key:12s}: {value}")

# ---------------------- 2. 网卡地址信息 ----------------------
print("\n\n=== 2. 网络接口地址信息 ===")
net_if_addrs = psutil.net_if_addrs()
for nic_name, addr_list in net_if_addrs.items():
# 过滤回环网卡和虚拟网卡,仅显示物理网卡
if "loopback" in nic_name.lower() or "虚拟" in nic_name:
continue
print(f"\n 网卡:{nic_name}")
ipv4_info = []
ipv6_info = []
mac_info = []
for addr in addr_list:
family_name = family_to_name(addr.family)
if family_name == "IPv4":
ipv4_info.append({
"IP地址": addr.address,
"子网掩码": addr.netmask or "无",
"广播地址": addr.broadcast or "无"
})
elif family_name == "IPv6":
ipv6_info.append({
"IP地址": addr.address,
"子网掩码": addr.netmask or "无"
})
elif family_name == "MAC":
mac_info.append(addr.address)

if ipv4_info:
print(" IPv4 地址:")
for info in ipv4_info:
print(f" - IP:{info['IP地址']} | 子网掩码:{info['子网掩码']} | 广播:{info['广播地址']}")
if ipv6_info:
print(" IPv6 地址:")
for info in ipv6_info:
print(f" - IP:{info['IP地址']} | 子网掩码:{info['子网掩码']}")
if mac_info:
print(f" MAC 地址:{mac_info[0]}")

# ---------------------- 3. 网卡状态信息 ----------------------
print("\n\n=== 3. 网络接口状态信息 ===")
net_if_stats = psutil.net_if_stats()
for nic_name, stats_data in net_if_stats.items():
if "loopback" in nic_name.lower() or "虚拟" in nic_name:
continue
print(f"\n 网卡:{nic_name}")
print(f" 连接状态:{'已启用' if stats_data.isup else '已禁用'}")
print(f" 双工模式:{duplex_to_name(stats_data.duplex)}")
print(f" 网卡速率:{stats_data.speed} Mbps" if stats_data.speed > 0 else " 网卡速率:未知")
print(f" 最大传输单元(MTU):{stats_data.mtu} 字节")

运行效果

  • 网络 IO 统计:网络IO统计输出
  • 网卡地址信息:网卡地址输出
  • 网卡状态信息:网卡状态输出

五、其他系统信息

5.1 系统启动时间

通过 psutil.boot_time() 获取系统启动时间戳,结合 datetime 格式化显示。

1
2
3
4
5
6
7
8
import psutil
from datetime import datetime

# 获取启动时间戳(秒级)
boot_ts = psutil.boot_time()
# 格式化为人类可读时间
boot_time = datetime.fromtimestamp(boot_ts).strftime("%Y-%m-%d %H:%M:%S")
print("系统启动时间:", boot_time)

运行效果

系统启动时间输出

5.2 扩展功能(可选)

  • psutil.users():获取当前登录用户列表(用户名、登录时间、终端)
  • psutil.disk_io_counters(perdisk=True):细分到单个磁盘的 IO 统计
  • psutil.net_connections():获取网络连接信息(TCP/UDP 连接状态、端口)

安装与兼容说明

安装命令

1
pip install psutil

兼容平台

  • Windows(XP+)、Linux、macOS、FreeBSD、OpenBSD、NetBSD、Solaris
  • Python 版本:3.6+

核心优势

  1. 跨平台统一 API:无需适配不同系统的命令行工具
  2. 轻量级:无依赖,安装包体积小
  3. 功能全面:覆盖系统资源监控核心场景
  4. 性能高效:底层基于系统调用,比解析命令行输出更快更稳定