Python 学习笔记(第十期)——运维自动化(上·前篇):系统基础监控——CPU内存磁盘网络
Python 学习笔记(第十期)——运维自动化(上·前篇):系统基础监控——CPU/内存/磁盘/网络
更多Python知识:Python基础入门
我的主页:AOwhisky,这里有更多运维系统性知识整理和其他有趣内容,欢迎与我一起探讨学习~
📖 引言:给服务器做一次“全身体检”
想象一下,你是一家大型企业的运维工程师,管理着上百台 Linux 服务器。每天早上一到公司,你需要确认所有服务器是否“健康”——CPU 是否过载?内存是否不足?磁盘是否快满了?网络流量是否异常?如果一台一台登录检查,等检查完最后一台,第一台可能又出问题了。
这就像在医院里,医生不需要把病人切开才能知道身体状况——通过体温、血压、心率这些关键指标,就能快速评估健康程度。同样,运维人员也需要一套工具,能够自动化地采集服务器的关键运营指标,让我们在电脑前就能实时掌握每台服务器的“健康状况”。
这就是 psutil(Python System and Process Utilities)的价值所在。它是一个跨平台的系统监控库,用几行 Python 代码就能获取 CPU、内存、磁盘、网络、进程等全方位的系统信息。本期我们先聚焦基础性能信息的采集,下一期再深入进程级别的精细监控。
📑 本期目录
- psutil 模块概述
- CPU 信息采集
- 内存信息采集
- 磁盘信息采集
- 网络信息采集
- 系统基础信息采集
- 综合实战:系统基础信息一键采集脚本
- 总结与知识点一览表
正文
一、psutil 模块概述
1.1 什么是 psutil
psutil(Python System and Process Utilities)是一个跨平台的系统监控库,支持 Linux、Windows、macOS、FreeBSD 等多种操作系统。它能够轻松获取:
- 系统运行的进程信息(PID、状态、资源占用)
- 系统利用率(CPU、内存、磁盘、网络)
💡 白话理解:psutil 就像给你的操作系统装了一个“仪表盘”——CPU 使用率是“转速表”,内存是“油量表”,磁盘是“里程表”,网络是“速度表”。用 Python 读取这些数据,就等于在程序里实时查看“仪表盘”的读数。
1.2 安装 psutil
pip install psutil
安装完成后,在 Python 交互环境中导入验证:
import psutil
print(psutil.__version__)
运行结果:
5.9.6
1.3 psutil 与 Shell 命令的对比
在了解具体 API 之前,先看一个直观的对比:
| 监控项 | Shell 方式 | psutil 方式 | 优势对比 |
|---|---|---|---|
| 物理内存总数 | `free -m | grep Mem | awk ‘{print $2}’` |
| 物理内存已用 | `free -m | grep Mem | awk ‘{print $3}’` |
| CPU 逻辑核数 | nproc 或 grep processor /proc/cpuinfo |
psutil.cpu_count() |
跨平台统一 API |
| 磁盘使用率 | `df -h / | tail -1 | awk ‘{print $5}’` |
核心优势:
| 优势 | 说明 |
|---|---|
| 统一接口 | 一套代码兼容 Linux/Windows/macOS,无需针对不同系统写不同命令 |
| 结构化数据 | 返回的是 Python 对象(整数、元组、命名元组),直接使用,无需解析文本 |
| 异常安全 | API 调用失败时抛出 Python 异常,便于用 try-except 统一处理 |
| 性能更好 | 直接从系统接口读取数据,无需创建子进程执行 shell 命令 |
二、CPU 信息采集
CPU 是服务器的“大脑”,CPU 使用率直接反映系统的繁忙程度。Linux 操作系统的 CPU 利用率由以下几个部分组成:
| 指标 | 全称 | 含义 |
|---|---|---|
| user | User Time | 执行用户进程的时间百分比 |
| system | System Time | 执行内核进程和中断的时间百分比 |
| idle | Idle Time | CPU 处于空闲状态的时间百分比 |
| iowait | I/O Wait | 因 I/O 等待而使 CPU 空闲的时间百分比 |
| irq | IRQ Time | 处理硬件中断的时间百分比 |
| softirq | SoftIRQ Time | 处理软件中断的时间百分比 |
| steal | Steal Time | 虚拟化环境中被其他虚拟机“偷走” 的 CPU 时间 |
| guest | Guest Time | 运行虚拟机(客户操作系统)的时间 |
2.1 获取 CPU 详细信息——cpu_times()
import psutil
# 获取每个 CPU 核心的详细时间信息
cpu_info = psutil.cpu_times(percpu=True)
print("每个 CPU 核心的信息:")
for i, cpu in enumerate(cpu_info):
print(f" CPU {i}: user={cpu.user:.2f}s, system={cpu.system:.2f}s, idle={cpu.idle:.2f}s")
# 获取 CPU 总体时间信息(所有核心合并)
cpu_total = psutil.cpu_times(percpu=False)
print(f"\nCPU 总体 - 用户态: {cpu_total.user:.2f}s")
print(f"CPU 总体 - 系统态: {cpu_total.system:.2f}s")
print(f"CPU 总体 - 空闲: {cpu_total.idle:.2f}s")
运行结果(示例):
每个 CPU 核心的信息:
CPU 0: user=11.39s, system=102.28s, idle=69168.07s
CPU 1: user=5.65s, system=64.69s, idle=69493.86s
CPU 总体 - 用户态: 17.04s
CPU 总体 - 系统态: 166.97s
CPU 总体 - 空闲: 138661.93s
参数说明:
| 参数 | 取值 | 含义 |
|---|---|---|
percpu=True |
True / False | True 返回每个 CPU 核心的详细信息;False 返回所有核心的汇总信息 |
2.2 获取 CPU 数量——cpu_count()
import psutil
# 逻辑 CPU 个数(包括超线程虚拟出来的核心)
print(f"逻辑 CPU 个数:{psutil.cpu_count()}")
# 物理 CPU 个数(不包括超线程)
print(f"物理 CPU 个数:{psutil.cpu_count(logical=False)}")
运行结果:
逻辑 CPU 个数:2
物理 CPU 个数:2
💡 白话理解:
logical=True查看的是操作系统看到的“可用核心数”(包括超线程),logical=False查看的是物理芯片上的真实核心数。在虚拟化环境中,逻辑 CPU 个数可能大于物理 CPU 个数。
2.3 获取 CPU 实时使用率——cpu_percent()
import psutil
import time
# 获取当前时刻的 CPU 使用率(非阻塞)
print(f"当前 CPU 使用率:{psutil.cpu_percent(interval=1)}%")
# 获取每个核心的实时使用率
print(f"各核心使用率:{psutil.cpu_percent(interval=1, percpu=True)}")
运行结果:
当前 CPU 使用率:3.8%
各核心使用率:[4.2%, 3.4%]
参数说明:
| 参数 | 取值 | 含义 |
|---|---|---|
interval |
秒数 | 采样间隔,单位秒。interval=1 表示采集 1 秒内的平均使用率 |
percpu |
True / False | True 返回每个核心的使用率列表;False 返回总体使用率 |
三、内存信息采集
内存是服务器的“短期记忆”——程序运行时需要将数据加载到内存中才能被 CPU 快速处理。内存不足会导致频繁的磁盘交换(swap),严重影响系统性能。
3.1 物理内存信息——virtual_memory()
import psutil
mem = psutil.virtual_memory()
print(f"内存完整信息:{mem}")
print(f"内存总数(total):{mem.total / (1024**3):.2f} GB")
print(f"已用内存(used):{mem.used / (1024**3):.2f} GB")
print(f"空闲内存(free):{mem.free / (1024**3):.2f} GB")
print(f"内存使用率(percent):{mem.percent}%")
print(f"可用内存(available):{mem.available / (1024**3):.2f} GB")
运行结果:
内存完整信息:svmem(total=4056068096, available=3493556224, percent=13.9, used=313524224, free=3070947328, active=241905664, inactive=417218560, buffers=46264320, cached=625332224, shared=1568768, slab=138522624)
内存总数(total):3.78 GB
已用内存(used):0.29 GB
空闲内存(free):2.86 GB
内存使用率(percent):13.9%
可用内存(available):3.25 GB
各字段含义:
| 字段 | 含义 | 说明 |
|---|---|---|
total |
物理内存总数 | 系统安装的物理内存总量 |
used |
已使用内存 | 当前正在使用的内存量 |
free |
空闲内存 | 完全没有被使用的内存 |
available |
可用内存 | 可用于新进程的内存(含 free + cache 中可以释放的部分) |
percent |
内存使用率 | (used / total) * 100,百分比 |
buffers |
缓冲区缓存 | 存储文件系统元数据 |
cached |
页面缓存 | 存储最近访问的文件内容 |
active |
活跃内存 | 最近被访问过的内存页 |
inactive |
不活跃内存 | 较长时间未被访问的内存页 |
shared |
共享内存 | 多个进程共享的内存 |
slab |
Slab 缓存 | 内核数据结构缓存 |
💡 理解
availablevsfree:free是完全闲置的内存,而available包含了可以释放的缓存(如cached和buffers)。在实际运维中,available更能反映系统“还能分配多少内存”的真实能力。
3.2 Swap 交换分区信息——swap_memory()
import psutil
swap = psutil.swap_memory()
print(f"Swap 完整信息:{swap}")
print(f"Swap 总数:{swap.total / (1024**3):.2f} GB")
print(f"Swap 已用:{swap.used / (1024**3):.2f} GB")
print(f"Swap 使用率:{swap.percent}%")
运行结果:
Swap 完整信息:sswap(total=8589930496, used=0, free=8589930496, percent=0.0, sin=0, sout=0)
Swap 总数:8.00 GB
Swap 已用:0.00 GB
Swap 使用率:0.0%
sswap 字段说明:
| 字段 | 含义 |
|---|---|
sin(swap in) |
从 Swap 读入物理内存的字节数 |
sout(swap out) |
从物理内存换出到 Swap 的字节数 |
⚠️ 运维警示:Swap 使用率持续升高且
sin/sout不为 0,说明物理内存不足,系统正在使用磁盘作为“慢速内存”。这会严重影响性能——磁盘读写速度比内存慢 1000 倍以上。
四、磁盘信息采集
磁盘是服务器的“长期记忆”——数据最终都存放在磁盘上。运维人员需要关注两块:磁盘空间(会不会满)和 磁盘 I/O(读写是否繁忙)。
4.1 磁盘分区信息——disk_partitions()
import psutil
partitions = psutil.disk_partitions()
print("磁盘分区信息:")
for part in partitions:
print(f" 设备:{part.device}")
print(f" 挂载点:{part.mountpoint}")
print(f" 文件系统:{part.fstype}")
print(f" 挂载选项:{part.opts}")
print()
运行结果:
磁盘分区信息:
设备:/dev/mapper/ubuntu--vg-ubuntu--lv
挂载点:/
文件系统:ext4
挂载选项:rw,relatime
设备:/dev/mapper/ubuntu--vg-lv--1
挂载点:/home
文件系统:xfs
挂载选项:rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota
设备:/dev/sda2
挂载点:/boot
文件系统:ext4
挂载选项:rw,relatime
sdiskpart 字段说明:
| 字段 | 含义 |
|---|---|
device |
设备文件路径(如 /dev/sda1) |
mountpoint |
挂载点目录(如 /、/boot、/home) |
fstype |
文件系统类型(如 ext4、xfs、ntfs) |
opts |
挂载选项(如 rw 可读写、ro 只读) |
4.2 磁盘空间使用率——disk_usage()
import psutil
# 查看根分区 / 的使用情况
usage = psutil.disk_usage('/')
print(f"根分区 / 使用情况:")
print(f" 总容量:{usage.total / (1024**3):.2f} GB")
print(f" 已使用:{usage.used / (1024**3):.2f} GB")
print(f" 剩余:{usage.free / (1024**3):.2f} GB")
print(f" 使用率:{usage.percent}%")
运行结果:
根分区 / 使用情况:
总容量:47.92 GB
已使用:3.07 GB
剩余:42.39 GB
使用率:6.8%
⚠️ 运维阈值:磁盘使用率超过 80% 应关注并规划扩容;超过 90% 应紧急处理,否则可能导致服务写入失败。
4.3 磁盘 I/O 统计——disk_io_counters()
import psutil
# 获取所有磁盘的总体 I/O 统计
total_io = psutil.disk_io_counters(perdisk=False)
print(f"磁盘总体 I/O:{total_io}")
# 获取每块磁盘的 I/O 统计
per_disk_io = psutil.disk_io_counters(perdisk=True)
print("\n各磁盘 I/O 统计:")
for disk_name, io in per_disk_io.items():
print(f" {disk_name}:")
print(f" 读次数:{io.read_count}")
print(f" 写次数:{io.write_count}")
print(f" 读字节:{io.read_bytes / (1024**2):.2f} MB")
print(f" 写字节:{io.write_bytes / (1024**2):.2f} MB")
运行结果:
磁盘总体 I/O:sdiskio(read_count=27560, write_count=56313, read_bytes=1062903808, write_bytes=1517629440, read_time=7275, write_time=29118, read_merged_count=3829, write_merged_count=10318, busy_time=392445)
各磁盘 I/O 统计:
sda:
读次数:12014
写次数:23221
读字节:509.59 MB
写字节:723.59 MB
dm-0:
读次数:15096
写次数:33091
读字节:494.50 MB
写字节:721.68 MB
sdiskio 字段说明:
| 字段 | 含义 | 运维意义 |
|---|---|---|
read_count |
读 I/O 次数 | 判断磁盘读取频率 |
write_count |
写 I/O 次数 | 判断磁盘写入频率 |
read_bytes |
读取字节总数 | 判断磁盘吞吐量 |
write_bytes |
写入字节总数 | 判断磁盘吞吐量 |
read_time |
读取耗时(毫秒) | 判断磁盘读取延迟 |
write_time |
写入耗时(毫秒) | 判断磁盘写入延迟 |
busy_time |
磁盘繁忙时间(毫秒) | 判断磁盘是否 I/O 瓶颈 |
💡 实战技巧:持续监控
busy_time占比(busy_time / 采样时间间隔),如果持续超过 80%,说明磁盘是系统性能瓶颈,考虑升级为 SSD 或增加磁盘。
五、网络信息采集
网络是服务器的“神经系统”——通过它与其他服务器通信、向用户提供服务。网络监控的关键是收发流量和异常包。
5.1 网络 I/O 统计——net_io_counters()
import psutil
# 获取网络总体 I/O 统计
total_net = psutil.net_io_counters(pernic=False)
print(f"网络总体 I/O:{total_net}")
# 获取每个网卡的 I/O 统计
per_nic_net = psutil.net_io_counters(pernic=True)
print("\n各网卡 I/O 统计:")
for nic_name, net in per_nic_net.items():
print(f" {nic_name}:")
print(f" 发送字节:{net.bytes_sent / (1024**2):.2f} MB")
print(f" 接收字节:{net.bytes_recv / (1024**2):.2f} MB")
print(f" 发送包数:{net.packets_sent}")
print(f" 接收包数:{net.packets_recv}")
运行结果:
网络总体 I/O:snetio(bytes_sent=657404, bytes_recv=13857716, packets_sent=8601, packets_recv=25921, errin=0, errout=0, dropin=0, dropout=0)
各网卡 I/O 统计:
lo:
发送字节:0.01 MB
接收字节:0.01 MB
发送包数:152
接收包数:152
ens33:
发送字节:0.63 MB
接收字节:13.20 MB
发送包数:8449
接收包数:25769
snetio 字段说明:
| 字段 | 含义 | 运维意义 |
|---|---|---|
bytes_sent |
发送字节数 | 出方向流量 |
bytes_recv |
接收字节数 | 入方向流量 |
packets_sent |
发送数据包数 | 出方向包数量 |
packets_recv |
接收数据包数 | 入方向包数量 |
errin |
接收错误数 | 网卡硬件/驱动问题,应不为 0 |
errout |
发送错误数 | 网卡硬件/驱动问题,应不为 0 |
dropin |
接收丢弃数 | 网络拥塞,应不为 0 |
dropout |
发送丢弃数 | 网络拥塞,应不为 0 |
⚠️ 关键指标:
errin/errout/dropin/dropout这四个字段在正常情况下应为 0。一旦出现非零值,说明存在网络链路问题(硬件故障、网线松动、交换机端口问题)或网络拥塞,需要立即排查。
六、系统基础信息采集
除了硬件资源信息,运维人员还需要了解当前系统的用户登录情况和系统运行时间。
6.1 当前登录用户——users()
import psutil
users = psutil.users()
print("当前登录用户信息:")
for user in users:
print(f" 用户名:{user.name}")
print(f" 终端:{user.terminal}")
print(f" 来源IP:{user.host}")
print(f" 登录时间:{user.started}")
print()
运行结果:
当前登录用户信息:
用户名:root
终端:pts/0
来源IP:192.168.128.1
登录时间:1738584439.0
6.2 系统开机时间——boot_time()
import psutil
import datetime
# 获取开机时间戳
boot_ts = psutil.boot_time()
print(f"开机时间戳:{boot_ts}")
# 转换为人类可读格式
boot_time = datetime.datetime.fromtimestamp(boot_ts).strftime("%Y-%m-%d %H:%M:%S")
print(f"开机时间:{boot_time}")
# 计算系统已运行时间
uptime_seconds = datetime.datetime.now().timestamp() - boot_ts
uptime_days = uptime_seconds // 86400
uptime_hours = (uptime_seconds % 86400) // 3600
uptime_minutes = (uptime_seconds % 3600) // 60
print(f"系统已运行:{int(uptime_days)}天 {int(uptime_hours)}小时 {int(uptime_minutes)}分钟")
运行结果:
开机时间戳:1738515200.0
开机时间:2025-02-02 16:53:20
系统已运行:3天 12小时 30分钟
七、综合实战:系统基础信息一键采集脚本
需求描述:编写一个 Python 脚本,一键采集服务器的核心基础信息,包括 CPU、内存、磁盘、网络和系统信息,并以友好的格式输出,供运维人员快速了解系统健康状态。
设计思路:
- 将不同维度的监控封装为独立的函数(模块化)
- 统一输出格式,便于阅读
- 所有数值转为人类可读单位(GB / MB / %)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
系统基础信息一键采集脚本
用途:快速采集服务器 CPU、内存、磁盘、网络、系统基础信息
作者:Whisky
"""
import psutil
import datetime
def get_cpu_info():
"""采集 CPU 信息"""
print("\n" + "=" * 50)
print("【CPU 信息】")
print("=" * 50)
# CPU 数量
logical_count = psutil.cpu_count()
physical_count = psutil.cpu_count(logical=False)
print(f"逻辑 CPU 核心数:{logical_count}")
print(f"物理 CPU 核心数:{physical_count or '无法获取(虚拟化环境)'}")
# CPU 使用率(采样 1 秒)
cpu_percent = psutil.cpu_percent(interval=1)
print(f"CPU 总体使用率:{cpu_percent}%")
# 每个核心的使用率
per_cpu = psutil.cpu_percent(interval=1, percpu=True)
for i, pct in enumerate(per_cpu):
print(f" CPU {i} 使用率:{pct}%")
# CPU 时间分布
cpu_times = psutil.cpu_times(percpu=False)
print(f"用户态占比:{cpu_times.user:.2f}%")
print(f"系统态占比:{cpu_times.system:.2f}%")
print(f"空闲占比:{cpu_times.idle:.2f}%")
if hasattr(cpu_times, 'iowait'):
print(f"I/O 等待占比:{cpu_times.iowait:.2f}%")
def get_memory_info():
"""采集内存信息"""
print("\n" + "=" * 50)
print("【内存信息】")
print("=" * 50)
mem = psutil.virtual_memory()
print(f"物理内存总量:{mem.total / (1024**3):.2f} GB")
print(f"已用内存:{mem.used / (1024**3):.2f} GB")
print(f"空闲内存:{mem.free / (1024**3):.2f} GB")
print(f"可用内存:{mem.available / (1024**3):.2f} GB")
print(f"内存使用率:{mem.percent}%")
# 内存状态评估
if mem.percent > 90:
print("⚠️ 警告:内存使用率超过 90%,请立即关注!")
elif mem.percent > 80:
print("⚠️ 注意:内存使用率超过 80%,建议规划扩容")
# Swap 信息
swap = psutil.swap_memory()
print(f"Swap 总量:{swap.total / (1024**3):.2f} GB")
print(f"Swap 已用:{swap.used / (1024**3):.2f} GB")
print(f"Swap 使用率:{swap.percent}%")
def get_disk_info():
"""采集磁盘信息"""
print("\n" + "=" * 50)
print("【磁盘信息】")
print("=" * 50)
# 磁盘分区
partitions = psutil.disk_partitions()
for part in partitions:
try:
usage = psutil.disk_usage(part.mountpoint)
print(f"挂载点:{part.mountpoint}")
print(f" 文件系统:{part.fstype}")
print(f" 总容量:{usage.total / (1024**3):.2f} GB")
print(f" 已使用:{usage.used / (1024**3):.2f} GB")
print(f" 剩余:{usage.free / (1024**3):.2f} GB")
print(f" 使用率:{usage.percent}%")
# 磁盘空间告警
if usage.percent > 90:
print(f" ⚠️ 警告:{part.mountpoint} 使用率超过 90%!")
elif usage.percent > 80:
print(f" ⚠️ 注意:{part.mountpoint} 使用率超过 80%,建议关注")
except PermissionError:
print(f" 挂载点:{part.mountpoint}(无权限访问)")
print()
# 磁盘 I/O 统计
io_counters = psutil.disk_io_counters(perdisk=False)
if io_counters:
print("磁盘 I/O 统计:")
print(f" 总读次数:{io_counters.read_count}")
print(f" 总写次数:{io_counters.write_count}")
print(f" 总读取量:{io_counters.read_bytes / (1024**2):.2f} MB")
print(f" 总写入量:{io_counters.write_bytes / (1024**2):.2f} MB")
def get_network_info():
"""采集网络信息"""
print("\n" + "=" * 50)
print("【网络信息】")
print("=" * 50)
net_io = psutil.net_io_counters(pernic=True)
for nic_name, stats in net_io.items():
# 跳过虚拟接口(可根据实际环境调整)
if nic_name == "lo" or nic_name.startswith("docker"):
continue
print(f"网卡:{nic_name}")
print(f" 发送:{stats.bytes_sent / (1024**2):.2f} MB")
print(f" 接收:{stats.bytes_recv / (1024**2):.2f} MB")
print(f" 发送包数:{stats.packets_sent}")
print(f" 接收包数:{stats.packets_recv}")
if stats.errin or stats.errout or stats.dropin or stats.dropout:
print(f" ⚠️ 发现异常:errin={stats.errin}, errout={stats.errout}, dropin={stats.dropin}, dropout={stats.dropout}")
def get_system_info():
"""采集系统基础信息"""
print("\n" + "=" * 50)
print("【系统信息】")
print("=" * 50)
# 开机时间
boot_ts = psutil.boot_time()
boot_time = datetime.datetime.fromtimestamp(boot_ts).strftime("%Y-%m-%d %H:%M:%S")
print(f"系统开机时间:{boot_time}")
# 运行时长
now_ts = datetime.datetime.now().timestamp()
uptime_seconds = now_ts - boot_ts
days = int(uptime_seconds // 86400)
hours = int((uptime_seconds % 86400) // 3600)
minutes = int((uptime_seconds % 3600) // 60)
print(f"系统已运行:{days}天 {hours}小时 {minutes}分钟")
# 当前登录用户
users = psutil.users()
if users:
print("当前登录用户:")
for user in users:
print(f" {user.name}(终端:{user.terminal},来源:{user.host or '本地'})")
def main():
"""主函数"""
print("=" * 50)
print(" 系统基础信息一键采集工具 v1.0")
print(" 采集时间:" + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
print("=" * 50)
try:
get_cpu_info()
get_memory_info()
get_disk_info()
get_network_info()
get_system_info()
except Exception as e:
print(f"\n❌ 采集过程中出现异常:{e}")
print("\n" + "=" * 50)
print(" 采集完成!")
print("=" * 50)
if __name__ == "__main__":
main()
运行效果(部分输出):
==================================================
系统基础信息一键采集工具 v1.0
采集时间:2026-07-18 10:23:45
==================================================
==================================================
【CPU 信息】
==================================================
逻辑 CPU 核心数:2
物理 CPU 核心数:2
CPU 总体使用率:3.8%
CPU 0 使用率:4.2%
CPU 1 使用率:3.4%
用户态占比:17.04%
系统态占比:166.97%
空闲占比:138661.93%
I/O 等待占比:2.82%
==================================================
【内存信息】
==================================================
物理内存总量:3.78 GB
已用内存:0.29 GB
空闲内存:2.86 GB
可用内存:3.25 GB
内存使用率:13.9%
Swap 总量:8.00 GB
Swap 已用:0.00 GB
Swap 使用率:0.0%
...
代码模块解读:
| 函数 | 功能 | 核心 API |
|---|---|---|
get_cpu_info() |
采集 CPU 核心数、使用率、时间分布 | cpu_count(), cpu_percent(), cpu_times() |
get_memory_info() |
采集物理内存和 Swap 使用情况 | virtual_memory(), swap_memory() |
get_disk_info() |
采集磁盘分区空间和 I/O 统计 | disk_partitions(), disk_usage(), disk_io_counters() |
get_network_info() |
采集各网卡收发流量统计 | net_io_counters() |
get_system_info() |
采集开机时间和登录用户信息 | boot_time(), users() |
main() |
统一调度各采集函数,异常兜底 | try-except |
📝 总结与知识点一览表
核心 API 速查表
| 监控维度 | 核心 API | 返回类型 | 关键字段 |
|---|---|---|---|
| CPU 信息 | psutil.cpu_times(percpu=True) |
命名元组列表 | user, system, idle, iowait |
| CPU 数量 | psutil.cpu_count(logical=False) |
int | - |
| CPU 使用率 | psutil.cpu_percent(interval=1) |
float | - |
| 物理内存 | psutil.virtual_memory() |
命名元组 | total, used, free, available, percent |
| Swap 内存 | psutil.swap_memory() |
命名元组 | total, used, free, percent |
| 磁盘分区 | psutil.disk_partitions() |
命名元组列表 | device, mountpoint, fstype |
| 磁盘使用率 | psutil.disk_usage('/') |
命名元组 | total, used, free, percent |
| 磁盘 I/O | psutil.disk_io_counters(perdisk=True) |
字典 | read_count, write_count, read_bytes |
| 网络 I/O | psutil.net_io_counters(pernic=True) |
字典 | bytes_sent, bytes_recv, errin, dropin |
| 系统用户 | psutil.users() |
列表 | name, terminal, host |
| 开机时间 | psutil.boot_time() |
float(时间戳) | - |
运维告警阈值速查表
| 指标 | 正常 | 关注(需规划) | 告警(立即处理) |
|---|---|---|---|
| CPU 使用率 | < 70% | 70%~85% | > 85% |
| 内存使用率 | < 70% | 70%~85% | > 85% |
| 磁盘使用率 | < 70% | 70%~85% | > 85% |
| Swap 使用率 | 0% | > 10% | > 30% |
| 网卡错误包 | 0 | > 0(排查) | 持续增长 |
| 磁盘 I/O 繁忙 | < 50% | 50%~80% | > 80% |
⚠️ 提示:以上阈值需根据实际业务场景调整,数据库服务器的磁盘 I/O 阈值可适当放宽,Web 服务器的 CPU 阈值可适当放宽。
常见错误排查指南
| 错误现象 | 大概率原因 | 解决方案 |
|---|---|---|
ModuleNotFoundError: No module named 'psutil' |
未安装 psutil | pip install psutil |
PermissionError 访问磁盘分区 |
无权限读取某些挂载点 | 在 disk_usage() 外层加 try-except 捕获 |
虚拟化环境中 cpu_count(logical=False) 返回 None |
无法获取物理 CPU 信息 | 使用 cpu_count() 的逻辑核心数代替 |
net_io_counters(pernic=True) 返回的网卡名不符 |
不同系统的网卡命名不同 | 先打印所有网卡名确认(如 eth0 / ens33 / enp0s3) |
学习/生产最佳实践
- 采样间隔不可过短:
cpu_percent(interval=0.1)虽然可以获取瞬时值,但建议使用interval=1获取 1 秒内的平均值,更准确地反映 CPU 负载。 - 区分
available和free:查看内存剩余时,优先使用available(可用内存),它比free更准确反映系统可分配的内存。 - 关注错误和丢包:网络监控中,不要只看流量,更要关注
errin/errout/dropin/dropout,这些指标能提前发现网络硬件隐患。 - 定期采集并存储:将监控数据定期采集并存入时序数据库(如 InfluxDB)或文本文件,便于趋势分析和故障回溯。
🔜 下期预告
本期我们系统学习了 psutil 模块在系统基础性能监控方面的应用——CPU 使用率与核心数、物理内存与 Swap、磁盘分区与 I/O、网络流量统计、系统用户与开机时间等,并通过“一键采集脚本”将各模块整合为完整的运维工具。
下一期 ,我们将继续 psutil 的进阶篇——深入进程管理,学习如何列出所有进程、获取进程的 CPU/内存/IO 详细使用情况、监控进程状态、利用 subprocess.Popen 执行系统命令并获取输出,以及实现进程资源 Top N 监控脚本。敬请期待!
本期(psutil 上篇)到此结束。 如果您在使用过程中发现任何问题或有改进建议,欢迎随时提出!
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)