news 2026/9/28 8:30:49

psutil 系统监控实战:用 Python 实现 CPU、内存与进程管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
psutil 系统监控实战:用 Python 实现 CPU、内存与进程管理

psutil 大概是 Python 生态里最被低估的一个库,很多人写脚本时会优先去翻ps、top、free这些命令,或者用os模块拼拼凑凑,结果要跨平台时一团乱,要拿进程详细信息时更是无从下手。这个看着不起眼的库,其实把系统层面的 CPU、内存、磁盘、网络、进程、传感器信息全部收拢到了同一套优雅的 API 里,装完pip install psutil之后,你就能用几行 Python 拿到本机全部关键状态。这些年我在 Linux 服务器上做资源监控、自动告警、进程异常排查,几乎所有脚本的底层都是 psutil,这篇文章就把我实际用下来的经验完整写出来,从核心概念到 30 行代码的监控报警脚本,一次性讲透。

1. psutil 是什么,它凭什么成为系统监控的事实标准

1.1 一句话理解 psutil 的定位

psutil 是 Python 的系统监控和进程管理库,全称是 "process and system utilities",它做的事情说白了就是把操作系统的系统调用封装成 Python 对象。你在终端里敲top看到的 CPU 占用、free看到的内存情况、df -h看到的磁盘使用、ps aux看到的进程列表,psutil 都能用函数直接拿出来,而且是跨平台的。同一段代码在 Linux、Windows、macOS 上都能跑,不需要针对不同系统写不同的解析逻辑,这是它比直接调用系统命令强得多的根本原因。

很多人会问,直接用os.popen('ps aux')然后字符串解析不就行了吗?确实能行,但这种方案极其脆弱。系统命令的输出格式会因为发行版不同、语言环境不同、psutil 版本不同而变化,而且每次调用都要启动一个新进程,性能开销大。psutil 底层直接走的是 C 语言的系统 API,比如在 Linux 上读取/proc文件系统,效率高得多,拿到的数据也是结构化对象,直接访问属性就行,不用对付字符串切分这种脏活。

这个库从 2009 年一路维护到现在,经历了 Python 2 到 Python 3 的完整迁移,API 设计得很稳定,生态里大量上层工具(比如django-storages、celery、gunicorn、locust)都在用它做系统资源统计。我自己用下来的体感是:psutil 就是 Python 世界访问系统资源的标准入口,它在绝大多数场景下都不该被绕过。

1.2 主要能力地图:CPU、内存、磁盘、网络、进程、传感器

psutil 的能力可以分成六大块,我列个清晰的对应关系出来:

能力维度核心函数你能拿到什么
CPUcpu_times()、cpu_percent()、cpu_count()、cpu_freq()使用率、负载、核心数、主频、各核心独立统计
内存virtual_memory()、swap_memory()总量、已用、可用、缓冲区、交换分区信息
磁盘disk_partitions()、disk_usage()、disk_io_counters()分区列表、挂载点使用率、读写字节数、IO 次数
网络net_io_counters()、net_connections()、net_if_addrs()网卡流量、连接状态、端口占用、网卡地址
进程process_iter()、Process()进程 PID、父进程、命令行、内存占用、CPU 时间、打开的文件
传感器sensors_temperatures()、sensors_fans()、sensors_battery()主板温度、风扇转速、笔记本电量

有了这一套,你能做的事就非常多了。最简单的就是我下面要讲的实时资源监控脚本,复杂一点的可以做进程行为审计(比如发现某进程压榨 CPU 超过阈值自动发告警)、可以做服务健康检查(端口挂了自动拉起进程)、可以做负载生成(配合 threads 和 Process 类手工控制进程数)。这套能力和顶层工具链配合起来,可以让一个没什么基础设施的小团队,也能用十来行代码打造出自己的监控体系。

2. 上手准备:安装、导入与基本用法里的细节

2.1 安装方式和第一次调用

安装没有任何特殊难度,常规pip即可。如果你管理着多台机器,建议用虚拟环境加requirements.txt固定版本,避免上游 API 变动导致脚本失效。psutil 的版本迭代里偶尔会有接口调整,比如某些函数返回结果增加了字段,你的代码如果用了._fields之类的底层属性就可能被影响,所以固定版本在监控服务场景里非常值得做。

pip install psutil # 安装后确认版本 python -c "import psutil; print(psutil.__version__)"

装好之后,一个最简单的调用就能让你立刻感受到 psutil 的直观。比如取内存信息:

import psutil mem = psutil.virtual_memory() print(mem.total / (1024 ** 3)) # 总内存,单位 GB print(mem.available / (1024 ** 3)) print(f"内存使用率: {mem.percent}%")

virtual_memory()返回的是一个svmem具名元组,字段有total、available、percent、used、free、active、inactive、buffers、cached、shared、slab。不同操作系统返回的字段不完全一样,比如 Windows 上就没有inactive,所以跨平台脚本最好只依赖total、available、used、free、percent这种通用字段。

2.2 必须搞懂的缓存机制与百分比计算逻辑

第一次用cpu_percent()的人几乎都会踩到一个坑:第一次调用返回的是 0.0。不是因为你的 CPU 真的空闲,而是cpu_percent()默认计算的是“自上一次调用以来的使用率”,第一次调用时没有基准,所以返回 0.0。这背后的机制有点像汽车的平均油耗表,刚通电显示的是上一次清零后的数据,跑一段才有意义。

解决办法很直接:要么先调用一次做热身,要么使用interval参数,让它自己等一段时间再采集。比如psutil.cpu_percent(interval=1)会阻塞一秒,返回这一秒内的平均使用率。实时监控场景里,我会用这种方式:

import time import psutil # 热身调用,丢弃第一次的 0.0 _ = psutil.cpu_percent() while True: cpu = psutil.cpu_percent(interval=1) print(f"CPU 使用率: {cpu}%") time.sleep(0.5)

注意我在interval=1之后又sleep(0.5),这样实际的采集周期大约 1.5 秒,既能保证数据平滑,又不会让 CPU 监控本身就变成一个高负载进程。编程里有个经验法则:监控工具的自我开销必须控制在 1% 以内,psutil 的纯函数调用开销非常小,但如果你在循环里频繁构造Process对象、遍历所有进程、还逐个统计命令行,那么开销就会明显上升,这点在进程管理部分会再展开。

3. CPU 与内存监控:最常用的两个维度深入拆解

3.1 不只是百分比:CPU 时间、按核统计与频率识别瓶颈

cpu_percent()适合快速判断系统是否繁忙,但要定位性能瓶颈,光看一个百分比远远不够。我排查线上问题时,有一套固定的观察路径:先看整体cpu_percent,然后立刻看cpu_times()里的user、system、iowait分布,再看有没有进程在猛刷单核负荷。

cpu_times()返回的是 CPU 累计时间(单位秒),在 Linux 上包含user、system、idle、iowait、irq、softirq、steal、guest等字段。用两次采样做差值,就能算出某段时间内 CPU 花在用户态、内核态和等待 IO 上的比例。下面是我常用的一个慢速 IO 检测示例:

import psutil import time def cpu_io_wait_sample(duration=2): t1 = psutil.cpu_times() time.sleep(duration) t2 = psutil.cpu_times() total = sum(t2) - sum(t1) iowait = (t2.iowait - t1.iowait) / total * 100 if total else 0 user = (t2.user - t1.user) / total * 100 if total else 0 system = (t2.system - t1.system) / total * 100 if total else 0 return {"user": user, "system": system, "iowait": iowait} print(cpu_io_wait_sample())

如果iowait长期超过 30%,基本可以断定瓶颈在磁盘 IO 而不是 CPU 算力不够。这个时候去看psutil.disk_io_counters()的read_time和write_time变化,就能进一步定位是不是某块盘在读写上卡住了。

单核视角也有价值。cpu_percent(percpu=True)返回每个物理核心的使用率列表,如果某个核心接近 100% 而其他核心空闲,这多半是 Python GIL 或者某个不并发线程导致的倾斜负载。这种“假多核瓶颈”在跑爬虫、跑数据分析脚本时特别常见,看到这种分布,我会直接去process_iter()里找出哪一个进程的cpu_num()异常,再决定是否要改代码结构。

3.2 内存里被忽略的那几个字段:available 与 cached 的真实含义

virtual_memory()里大家最熟悉的可能是percent,但如果你只看percent判断服务器内存紧张,大概率会误判。Linux 的内存缓存机制决定了空闲内存看起来很少:文件缓存(cached)和内核缓冲区(buffers)占用了大量“看似已用”的内存,系统实际上随时可以把这些缓存释放出来给新进程用。所以真正决定系统还能不能扛住新进程的是available,这个字段的值约等于free + buffers + cached(精确计算逻辑更复杂)。psutil 的percent已经在较新版本里基于available做了修正,比你自己用used / total算出来的更合理。

used和available的差别你一定要理解清楚。很多新手写监控脚本用mem.used / mem.total算内存使用率,在刚启动的大内存机器上会看到一个虚高的值,因为 Linux 把磁盘文件预读到了缓存里。用 psutil 官方推荐的方式,直接拿mem.percent是最省事的;如果要自己算,请记住基准是available而不是free。

swap_memory()返回的sin和sout字段是很有用的,它们分别表示从磁盘换入、换出的字节数。如果sout持续增长,说明物理内存已经不够用,系统正在把内存页疯狂写到交换分区,这个时候机器会明显卡顿。线上排查我会同时看 swap 使用率和sout增量,两个指标同时飙升,基本可以直接定位为内存耗尽型问题。

4. 磁盘与网络监控:存储和流量的核心指标

4.1 磁盘分区、使用率遍历和 IO 计数

disk_usage('/')能直接拿到根分区的使用情况,返回total、used、free、percent。要遍历所有挂载点,用disk_partitions(all=False)。这里的all=False指的是只显示“真实物理磁盘分区”,如果你用all=True,/proc、/sys、/dev这些虚拟文件系统也会被列出来,它们大多占用内存或内核数据,统计磁盘使用率没有意义,只会干扰判断。想排除掉它们,最简单的方式是过滤fstype,比如只保留ext4、xfs、btrfs、ntfs、apfs等真实文件系统类型。

一个写监控脚本时常遇到的细节是:disk_usage()对 Windows 盘符路径和 Linux 挂载点要区分处理。跨平台覆盖时不要硬编码路径,建议遍历psutil.disk_partitions()后对每个挂载点依次disk_usage(pt.mountpoint)。注意,psutil.disk_usage()在访问一个已卸载或者权限受限的挂载点时会抛PermissionError或OSError,遍历时要 try 包一层。

import psutil # 对典型 Linux 服务器打印磁盘使用率 for part in psutil.disk_partitions(all=False): try: usage = psutil.disk_usage(part.mountpoint) print(f"{part.device} mounted on {part.mountpoint}: " f"{usage.percent}% used, {usage.free / (1024**3):.1f} GiB free") except PermissionError: print(f"跳过无权限挂载点: {part.mountpoint}")

磁盘 IO 层面的disk_io_counters()返回的信息里有几个关键字段:read_bytes、write_bytes、read_time、write_time、read_count、write_count。单纯看字节数没有绝对意义,要看增量。比如用两次采样算每秒读写速率,这是最简单的 IO 吞吐量监控方式,虽然不如 iostat 精确,但做告警阈值已经足够。

4.2 网络计数器与连接列表:从网卡流量到端口占用排查

网络监控最常用的是net_io_counters(),它返回所有网卡累计收发的字节数和数据包数。你只需要在两次采样之间计算差值,再除以时间间隔,就能得到每秒的实时入站/出站速率。我把这个功能封装成一个get_net_speed()函数,在定位“半夜带宽被打满”这种问题时帮了大忙。

import psutil import time last = psutil.net_io_counters(pernic=True) def net_speed(interval=1): global last time.sleep(interval) current = psutil.net_io_counters(pernic=True) speed = {} for nic in current: if nic in last: sent = (current[nic].bytes_sent - last[nic].bytes_sent) / interval recv = (current[nic].bytes_recv - last[nic].bytes_recv) / interval speed[nic] = {"up": sent, "down": recv} last = current return speed print(net_speed(2))

这个函数有个必须注意的地方:pernic=True时返回的是每个网卡的独立计数器,如果你直接不传pernic,得到的是全网卡汇总,两台机器的流速混在一起,可能掩盖某张内网卡跑满的问题。而bytes_sent和bytes_recv都是累计值,不是瞬时值,所以只拿一次是没有意义的,必须做差值。

net_connections()是一个容易踩坑的 API。它默认只返回当前用户能看到的连接;想看所有进程的连接,需要以 root 身份运行,并把参数设成psutil.net_connections(kind='all')。kind常见的可选值包括tcp、udp、unix,最常用的是tcp。在 Linux 上,遍历全部连接时开销不小,几百上千个连接就有明显的耗时,如果你的监控频率很高,要控制它的调用次数。

排除线上问题时,我常用net_connections()按端口反查占用进程:先筛选laddr.port == 某个端口的连接,提取pid,再用psutil.Process(pid)拿到进程名和命令行。这比lsof -i快,而且是纯 Python 的,直接在监控脚本里就能接续处理。

5. 进程管理:psutil 真正拉开差距的功能

5.1 进程快照的采集姿势:process_iter 与 as_dict

很多库只能看系统层面的量,psutil 能深入到“每个进程”这一层,这才是它真正的护城河。psutil.process_iter()是迭代所有进程的推荐入口,它比在/proc下一个个os.listdir再组装os.kill的方式好太多。重点在于它能配合attrs参数只取你关心的字段,让遍历开销可控:

import psutil for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']): try: print(proc.info) except psutil.NoSuchProcess: # 进程可能在遍历过程中已经退出 continue

这里proc.info是一个字典,包含你指定的字段。因为进程是动态的,遍历过程中一个进程可能刚好退出,或者变成了僵尸进程,访问它的属性就会抛NoSuchProcess、AccessDenied。代码里必须 try 接住这些异常,否则一个进程退出就会让整个监控脚本崩溃,这是所有进程遍历脚本都要记得的底线。

as_dict()则是把Process对象整体转成字典,它会把几乎所有属性一次取出来。看起来方便,但开销极大,每次都要访问几十个系统接口,在有很多进程的服务器上会非常慢。我现在的经验是:明确要什么字段就用attrs精确取,能用process_iter就不自己Process(pid)。as_dict()只在交互式排查单个进程时偶尔用用。

5.2 僵尸进程识别、信号发送与进程拉起

进程管理里有一个非常容易踩的现象:僵尸进程。它的含义是进程已经退出,但父进程没有调用wait()回收它的退出状态,所以 PID 还留在进程表里。僵尸进程不占 CPU 和内存(资源已释放),但大量堆积会让process_iter()变慢,也会让top显示异常。psutil 里识别僵尸进程非常方便:

import psutil for proc in psutil.process_iter(['pid', 'name', 'status']): if proc.info['status'] == psutil.STATUS_ZOMBIE: print(f"发现僵尸进程: {proc.info['pid']} {proc.info['name']}")

发现僵尸进程后,普通kill信号是杀不掉的,因为进程已经“死”过一次了。你需要做的是处理它的父进程——要么让父进程正常回收子进程,要么重启父进程。这一条我要特别强调,不然你对着僵尸 PID 发SIGKILL会发现毫无反应,还以为是自己代码写错了。

如果你想用 psutil 做服务守护,proc.terminate()发送SIGTERM,proc.kill()发送SIGKILL,proc.is_running()判断存活。一个常见的启停模式是这样的:

import os import psutil import subprocess proc = psutil.Process(12345) if proc.is_running() and proc.status() != psutil.STATUS_ZOMBIE: proc.terminate() # 等待最多 5 秒,超时再强杀 try: proc.wait(timeout=5) except psutil.TimeoutExpired: proc.kill()

这种优雅停机模式在服务管理脚本里非常实用:先给进程一个善后机会(SIGTERM),处理不了再强杀(SIGKILL)。如果发现进程不在,就直接用subprocess.Popen拉起来。把这一套放到定时任务里,小型服务的高可用就基本成型了。

6. 实战:写一个 30 行系统监控报警脚本

6.1 场景设定与阈值设计逻辑

前面的知识点串起来,就该做一个真正的项目了。我的需求很典型:一台 Linux 服务器上没有部署重量级监控平台,但我希望能在 CPU、内存、磁盘、网络、进程数五个维度出现异常时,第一时间通过标准输出留痕,方便后续接入告警系统(比如把内容打到日志里再由外部采集)。

阈值设计有一些通用经验,我给的这套参数比较适合普通的 4 核 8G 云主机:

指标告警阈值判断逻辑
CPU 使用率> 90%持续 3 个采样周期超过则触发
内存使用率> 85%检查virtual_memory().percent
磁盘使用率> 90%遍历根分区和/data等关键分区
网络入站速率> 200 MB/s按两次采样差值计算,单位换算
进程数> 500用len(psutil.pids())获取

多采样周期判定这个点,是新手最容易忽略的。CPU 瞬时冲到 95% 可能在跑一次小任务,不值得告警;持续 3 个周期说明真的有问题,告警才需要触发。这个逻辑能显著降低误报率。避免误报还有另一个做法:第一个采样周期只做标记,第二个周期才开始判定。

6.2 脚本代码与运行效果

脚本我控制在 30 行左右,重点注释加在关键业务逻辑上:

import time import psutil def check_thresholds(): alerts = [] # CPU:采样 1 秒的平均使用率,连续 3 次超过 90% 才告警 cpu_samples = [psutil.cpu_percent(interval=1) for _ in range(3)] if all(v > 90 for v in cpu_samples): alerts.append(f"CPU 持续高负载: {max(cpu_samples):.1f}%") # 内存:直接使用官方 percent(已基于 available 计算) mem = psutil.virtual_memory() if mem.percent > 85: alerts.append(f"内存使用率过高: {mem.percent:.1f}%") # 磁盘:只看根分区和常见数据分区 for part in psutil.disk_partitions(all=False): if part.fstype in ("ext4", "xfs", "btrfs"): usage = psutil.disk_usage(part.mountpoint) if usage.percent > 90: alerts.append(f"磁盘 {part.mountpoint} 使用率 {usage.percent:.1f}%") # 网络:计算 2 秒内的入站平均速率 n1 = psutil.net_io_counters() time.sleep(2) n2 = psutil.net_io_counters() incoming_speed = (n2.bytes_recv - n1.bytes_recv) / 2 / (1024 ** 2) if incoming_speed > 200: alerts.append(f"入站速率异常: {incoming_speed:.1f} MB/s") # 进程数:超过 500 视为异常 pids_len = len(psutil.pids()) if pids_len > 500: alerts.append(f"进程数过多: {pids_len}") return alerts if __name__ == "__main__": print("监控脚本启动,每 60 秒检查一次") while True: alert_list = check_thresholds() if alert_list: timestamp = time.strftime("%Y-%m-%d %H:%M:%S") for alert in alert_list: print(f"[{timestamp}] ALERT: {alert}") time.sleep(60)

运行起来之后,脚本每 60 秒做一次全面体检,只在真正异常时才打印告警日志。把标准输出重定向到文件或者对接系统日志服务,就能做到“异常可追踪”。我给好几台业务服务器装过类似的脚本,日常负载基本是零,因为psutil的调用开销都在毫秒级别。

6.3 这个脚本的扩展方向和改进思路

脚本虽然只有 30 行,但它的扩展空间非常大。第一是告警渠道:用smtplib发邮件,或者把输出打到/var/log/host_monitor.log再交给 logstash 采集,都很容易。第二是指标细化:网络速率可以按网卡分别统计,磁盘 IO 可以监控disk_io_counters()的延迟字段。第三是历史数据:用sqlite3把每次巡检结果存下来,就能画趋势图。

更进一步的思路是让监控脚本“会动手”.比如进程数异常时主动打印最占资源的 Top 进程,内存告警时自动抓取占用内存最多的前 5 个进程 PID 和命令行。我在生产环境里就是这么干的,告警信息里直接带上现场快照,省去登录服务器排查的时间。每一步改动都建立在 psutil 的同一套 API 上,没有额外学习成本,这是这个库最好的地方。

7. 常见问题与踩坑实录(速查表)

7.1 权限问题与僵尸进程

这一节要专门讲一讲我踩过的坑。第一个是权限问题。psutil.Process(pid).name()这类调用,如果目标进程属于别的用户,而你又不是 root,就会抛psutil.AccessDenied。这在普通用户跑监控脚本时非常常见。解决办法有两个:要么用 root 权限跑脚本,要么在遍历时捕获AccessDenied并跳过。后者更稳妥,因为生产环境不总是愿意把监控脚本跑成 root。

第二个坑是僵尸进程的cpu_percent()和memory_percent()会返回 0 或者直接抛异常,因为这类进程的系统资源已经回收,内核里只剩一个退出状态。你的遍历逻辑里如果不做状态判断,僵尸进程泛滥时会看到一堆异常日志。前面已经给了通过proc.info['status']判断的写法,在遍历大批进程时务必加上。

Linux 上还有个隐蔽坑:读取进程环境变量proc.environ()在权限不足时会抛AccessDenied。如果你只想拿命令行,用cmdline()或者name()就够了,不要画蛇添足取不必要的字段。字段越多,遍历就越慢,也越容易碰到权限异常。

7.2 首次数值的特殊性、单位换算与跨平台差异

cpu_percent()第一次调用返回 0.0 的问题,前面提过了;这里还有一个容易混淆的变体,就是Process(pid).cpu_percent()也是同样的“自上次调用以来”语义。所以如果你想统计某个进程从启动到现在的平均 CPU 使用率,正确写法是取两次采样加时间间隔,而不是调一次就拿来用。如果不做热身,第一次拿到的 0.0 可能会被当作业绩展示,误导判断。

单位换算是另一个高频出错点。psutil 里的内存、磁盘、网络数值,默认单位都是字节(bytes),不是 KB 也不是 MB。很多人直接把mem.used输出发现一个十几位的数字,然后一脸懵。换算经验是:看仪表数据用 GB(除以 1024 三次),看网络实时速度用 MB/s(除以 1024 两次再除以时间)。千万不要混淆 KB 和 KiB 的差异,psutil 底层用的是二进制单位,如果你用 1000 做除法,数据会有约 2% 的偏差,长期统计趋势虽然能看,但精细分析时会造成困扰。

跨平台差异是最容易被本地开发骗到的点。我在 Windows 上开发,Linux 上部署,这段经历让我很早就意识到:sensors_temperatures()在 Windows 上要么没有,要么返回空字典;disk_partitions(all=True)在 Windows 上的挂载点是一个盘符,在 Linux 上则要区分虚拟文件系统。写跨平台代码时,所有平台相关 API 都要包一层条件判断。此外,Windows 上某些net_connections(kind='unix')是不支持的,会直接抛NotImplementedError,这些都在官方文档里有明确说明,写代码前先看一眼对应平台的兼容表,能少踩一半的坑。

8. 把 psutil 用出真正的价值:从工具到体系

8.1 用进程树分析替代顶级命令排查

如果你只把 psutil 当作top的替代品,那它对你来说只是省了几行代码;但当你开始用它组织“进程树”,它就能帮你做更深刻的故障定位。psutil.process_iter()拿到所有进程后,用ppid字段构造父子关系树,再结合每个进程的 CPU 和内存占比,可以快速找出“哪个服务的哪个子进程在拖垮整台机器”。“找出问题进程”是监控的核心诉求,而不是仅仅展示数字。

我实际处理过一个线上事故,现象是机器负载高达 30,但top按 CPU 排序时看起来没有特别突出的进程,因为负载高不是 CPU 算力不够,而是大量进程处于不可中断睡眠状态(D状态),全部在等磁盘 IO。此时用 psutil 遍历status,就能把所有STATUS_DISK_SLEEP状态的进程筛出来,再往它们各自的 IO 统计上看一眼,立刻锁定是某块云盘性能骤降。这个排查思路用传统top很难一眼得出,但 psutil 只需几十行代码就解决了。

8.2 监控数据落地:与日志体系和其他工具的配合

psutil 拿到的监控数据如果不落地,价值就少了一半。我通常的做法是把告警指标输出成 JSON 单行,追加到日志文件里,再交给 filebeat、prometheus 的 exporter 或者自研采集器去处理。这里有个关键最佳实践:监控脚本本身必须轻量、稳定,不要在主流程里做重数据处理。psutil 的调用耗时受环境因素影响不小,遍历几百个进程时最差能达到秒级,所以高频数据采集(比如每秒一次)只建议采集 CPU、内存这类轻量指标;全量进程遍历可以放到低频率巡检任务里。

顺手分享一个我在多台机器上部署的经验:用cron或 systemd timer 运行监控脚本,而不是用while True常驻。原因有两点:一是常驻进程崩溃后很难自动恢复,二是定时任务天然适合“每次巡检、输出结果、退出”的模式,也方便单独测试某一次执行。只有需要持续平滑采集的场景,才适合常驻进程加interval采样。实践里我会根据指标特性混搭:慢指标用定时任务,快指标用常驻进程,再统一收集到同一个数据管道里。

我的实操体会

psutil 陪我排查过无数线上问题,从最开始的 “用 Python 看服务器状态” 到后来的自动告警、进程守护、数据采集,它的 API 始终没给我找过麻烦。如果你刚开始接触,我建议不要贪多,先把cpu_percent(interval=1)、virtual_memory().percent、disk_usage('/')、net_io_counters()这四个函数吃透,写一个每秒刷新的小面板,你会立刻找到掌控一台机器的感觉。然后再去啃process_iter()和异常处理,逐步构建自己的进程级监控能力。踩过权限、单位、首次数值这些坑之后,这个库用起来会非常顺手,也会成为你工具链里不可或缺的一环。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 8:30:45

给AI配一份不会过期的记忆:AGENTS.md与PROJECT.md实战指南

如果你也试过让 AI 助手帮你写科研代码,大概率经历过这种场面:上午刚让它改完数据预处理脚本,下午接着聊,它却忘了你项目的存储路径、变量命名习惯,甚至把核心实验假设理解偏了。我踩了无数次这种坑之后,开…

作者头像 李华
网站建设 2026/9/28 8:30:36

南昌seo方案避坑指南:备案不卡壳的实操手册

南昌seo方案避坑指南:备案不卡壳的实操手册 备案流程一头雾水?别急,这不仅是南昌本地企业做网站最头疼的环节,更是很多SEO从业者被甲方反复催促的痛点。我见过太多同行,代码写得飞起,结果卡在域名备案上,导致南昌seo方案迟迟无法落地,白白浪费了流量窗口期。…

作者头像 李华
网站建设 2026/9/28 8:30:35

三维出行×全场景智能:探路生态AWE2026首秀全解析

先给你撂一句实在话:刷完AWE2026前期流出的展区规划和概念图,我的第一反应是“这届有点东西”。不是那些千篇一律的大屏互联、或者把冰箱洗衣机再塞一块触摸屏的微创新——而是“三维出行”这个关键词,居然被堂而皇之地放进了家电网展的主舞台…

作者头像 李华
网站建设 2026/9/28 8:30:18

宁波网络营销怎么做:备案避坑指南与实操全案

宁波网络营销怎么做:备案避坑指南与实操全案 很多老板在宁波搞网络营销,第一步就卡在了ICP备案上,流程一头雾水,心里没底。别慌,这篇避坑指南就是为你准备的,直接讲干货。 运营目标与指标设定…

作者头像 李华
网站建设 2026/9/28 8:30:01

锁的分类全解析:从互斥锁到分布式锁,一篇讲透

前阵子技术群里有人问:常见的锁到底怎么分类?结果回答五花八门,有人报互斥锁、读写锁,有人直接把数据库的行锁表锁拍上来,还有人反问“你是说Win11锁屏壁纸不更新那个锁吗?”十来个人聊了半天,最…

作者头像 李华