使用Python+psutil開發(fā)一個簡易系統(tǒng)監(jiān)控工具
引言
在運維自動化、服務器巡檢、故障排查和資源告警場景中,經(jīng)常需要快速獲取機器的 CPU、內(nèi)存、磁盤和進程狀態(tài)。
如果只依賴系統(tǒng)命令,例如 Linux 下的 top、free、df,或者 Windows 下的任務管理器,自動化能力會比較弱。Python 的 psutil 庫正好解決了這個問題:它可以用統(tǒng)一的 Python API 獲取跨平臺系統(tǒng)信息,非常適合用來開發(fā)輕量級系統(tǒng)監(jiān)控腳本。
本文會從 psutil 基礎用法開始,逐步實現(xiàn)一個可以實時刷新的簡易系統(tǒng)監(jiān)控工具。
一、psutil 庫介紹
psutil 是 Python 中常用的系統(tǒng)和進程監(jiān)控庫,全稱可以理解為 process and system utilities。
它可以獲?。?/p>
- CPU 使用率、CPU 核心數(shù)、負載信息
- 內(nèi)存總量、已用內(nèi)存、可用內(nèi)存、使用率
- 磁盤分區(qū)、磁盤容量、磁盤使用率
- 網(wǎng)絡連接、網(wǎng)卡收發(fā)數(shù)據(jù)
- 當前運行的進程列表、進程 PID、進程名稱、CPU 占用、內(nèi)存占用
在運維自動化方向,psutil 常見用途包括:
- 編寫服務器巡檢腳本
- 定時采集系統(tǒng)資源指標
- 判斷服務進程是否存活
- 查找高 CPU 或高內(nèi)存進程
- 結(jié)合日志、郵件、企業(yè)微信或釘釘實現(xiàn)告警
- 作為監(jiān)控 Agent 的基礎模塊
安裝方式很簡單:
pip install psutil
驗證安裝:
import psutil print(psutil.cpu_count())
如果能夠輸出 CPU 核心數(shù)量,說明安裝成功。
二、獲取 CPU 使用率
CPU 是系統(tǒng)監(jiān)控中最核心的指標之一。使用 psutil.cpu_percent() 可以獲取 CPU 使用率。
import psutil
cpu_percent = psutil.cpu_percent(interval=1)
print(f"CPU 使用率:{cpu_percent}%")
這里的 interval=1 表示統(tǒng)計 1 秒內(nèi)的 CPU 使用情況。
也可以獲取每個 CPU 核心的使用率:
import psutil
cpu_per_core = psutil.cpu_percent(interval=1, percpu=True)
for index, percent in enumerate(cpu_per_core, start=1):
print(f"CPU 核心 {index}:{percent}%")
獲取 CPU 核心數(shù):
import psutil
logical_count = psutil.cpu_count(logical=True)
physical_count = psutil.cpu_count(logical=False)
print(f"邏輯核心數(shù):{logical_count}")
print(f"物理核心數(shù):{physical_count}")
在實際運維場景中,通常會重點關(guān)注整體 CPU 使用率。如果 CPU 長時間超過 80% 或 90%,就需要進一步排查是否存在異常進程、流量突增、死循環(huán)任務或定時任務集中運行等問題。
三、獲取內(nèi)存使用情況
內(nèi)存監(jiān)控可以使用 psutil.virtual_memory()。
import psutil
memory = psutil.virtual_memory()
print(f"內(nèi)存總量:{memory.total}")
print(f"已用內(nèi)存:{memory.used}")
print(f"可用內(nèi)存:{memory.available}")
print(f"內(nèi)存使用率:{memory.percent}%")
直接輸出字節(jié)數(shù)不太方便閱讀,可以封裝一個單位轉(zhuǎn)換函數(shù):
def format_bytes(size):
for unit in ["B", "KB", "MB", "GB", "TB"]:
if size < 1024:
return f"{size:.2f} {unit}"
size /= 1024
return f"{size:.2f} PB"
結(jié)合起來:
import psutil
def format_bytes(size):
for unit in ["B", "KB", "MB", "GB", "TB"]:
if size < 1024:
return f"{size:.2f} {unit}"
size /= 1024
return f"{size:.2f} PB"
memory = psutil.virtual_memory()
print(f"內(nèi)存總量:{format_bytes(memory.total)}")
print(f"已用內(nèi)存:{format_bytes(memory.used)}")
print(f"可用內(nèi)存:{format_bytes(memory.available)}")
print(f"內(nèi)存使用率:{memory.percent}%")
對服務器來說,內(nèi)存不足可能導致服務響應變慢、進程被系統(tǒng)終止、緩存命中率下降。運維腳本中一般會把內(nèi)存使用率作為告警條件之一。
四、獲取磁盤空間
磁盤空間可以通過 psutil.disk_usage() 獲取。
import psutil
disk = psutil.disk_usage("/")
print(f"磁盤總量:{disk.total}")
print(f"已用空間:{disk.used}")
print(f"剩余空間:{disk.free}")
print(f"磁盤使用率:{disk.percent}%")
如果希望查看所有磁盤分區(qū),可以使用 psutil.disk_partitions():
import psutil
def format_bytes(size):
for unit in ["B", "KB", "MB", "GB", "TB"]:
if size < 1024:
return f"{size:.2f} {unit}"
size /= 1024
return f"{size:.2f} PB"
partitions = psutil.disk_partitions()
for partition in partitions:
try:
usage = psutil.disk_usage(partition.mountpoint)
except PermissionError:
continue
print(f"設備:{partition.device}")
print(f"掛載點:{partition.mountpoint}")
print(f"文件系統(tǒng):{partition.fstype}")
print(f"總空間:{format_bytes(usage.total)}")
print(f"已用空間:{format_bytes(usage.used)}")
print(f"剩余空間:{format_bytes(usage.free)}")
print(f"使用率:{usage.percent}%")
print("-" * 40)
磁盤監(jiān)控非常重要。日志目錄、數(shù)據(jù)庫目錄、上傳文件目錄如果沒有清理策略,很容易出現(xiàn)磁盤被寫滿的問題。一旦磁盤滿了,常見后果包括服務無法寫日志、數(shù)據(jù)庫寫入失敗、容器啟動失敗等。
五、獲取進程信息
psutil 也可以獲取系統(tǒng)中的進程信息。常用方法是 psutil.process_iter()。
import psutil
for process in psutil.process_iter(["pid", "name", "cpu_percent", "memory_percent"]):
info = process.info
print(
f"PID={info['pid']}, "
f"名稱={info['name']}, "
f"CPU={info['cpu_percent']}%, "
f"內(nèi)存={info['memory_percent']:.2f}%"
)
在遍歷進程時,可能遇到權(quán)限不足或進程已經(jīng)退出的問題,所以正式腳本中通常要捕獲異常:
import psutil
for process in psutil.process_iter(["pid", "name", "cpu_percent", "memory_percent"]):
try:
info = process.info
print(info)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
如果要找出 CPU 占用較高的進程,可以排序:
import psutil
import time
# 第一次調(diào)用用于初始化 CPU 統(tǒng)計
for process in psutil.process_iter():
try:
process.cpu_percent(interval=None)
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
time.sleep(1)
processes = []
for process in psutil.process_iter(["pid", "name", "cpu_percent", "memory_percent"]):
try:
processes.append(process.info)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
top_processes = sorted(processes, key=lambda item: item["cpu_percent"], reverse=True)[:5]
for item in top_processes:
print(
f"PID={item['pid']}, "
f"名稱={item['name']}, "
f"CPU={item['cpu_percent']}%, "
f"內(nèi)存={item['memory_percent']:.2f}%"
)
這個功能在排查服務器負載過高時非常有用??梢钥焖俣ㄎ皇悄膫€ Python 程序、Java 服務、數(shù)據(jù)庫進程或其他后臺任務消耗了大量資源。
六、實時刷新系統(tǒng)狀態(tài)
系統(tǒng)監(jiān)控工具通常不是只執(zhí)行一次,而是每隔幾秒刷新一次狀態(tài)。
基本思路如下:
- 清空終端屏幕
- 獲取 CPU、內(nèi)存、磁盤、進程信息
- 格式化輸出
- 休眠指定秒數(shù)
- 循環(huán)執(zhí)行
清屏函數(shù)可以兼容 Windows、Linux 和 macOS:
import os
def clear_screen():
os.system("cls" if os.name == "nt" else "clear")
循環(huán)刷新:
import time
while True:
clear_screen()
print("系統(tǒng)狀態(tài)刷新中...")
time.sleep(2)
為了方便停止程序,可以捕獲 KeyboardInterrupt。用戶按 Ctrl + C 時,腳本可以優(yōu)雅退出。
try:
while True:
clear_screen()
print("系統(tǒng)狀態(tài)刷新中...")
time.sleep(2)
except KeyboardInterrupt:
print("監(jiān)控已停止")
七、制作一個簡易系統(tǒng)監(jiān)控腳本
下面實現(xiàn)一個完整腳本,功能包括:
- 顯示當前時間
- 顯示 CPU 核心數(shù)和 CPU 使用率
- 顯示內(nèi)存總量、可用內(nèi)存、內(nèi)存使用率
- 顯示所有磁盤分區(qū)空間
- 顯示 CPU 占用最高的前 5 個進程
- 每 2 秒自動刷新
- 支持
Ctrl + C停止
這個腳本適合用于入門級服務器巡檢,也可以繼續(xù)擴展為告警工具。
八、完整代碼
文件名可以保存為 system_monitor.py。
import os
import time
from datetime import datetime
import psutil
REFRESH_INTERVAL = 2
TOP_PROCESS_LIMIT = 5
def format_bytes(size):
"""Convert bytes to a human-readable string."""
for unit in ["B", "KB", "MB", "GB", "TB"]:
if size < 1024:
return f"{size:.2f} {unit}"
size /= 1024
return f"{size:.2f} PB"
def clear_screen():
os.system("cls" if os.name == "nt" else "clear")
def get_cpu_info():
return {
"logical_count": psutil.cpu_count(logical=True),
"physical_count": psutil.cpu_count(logical=False),
"percent": psutil.cpu_percent(interval=1),
"per_core": psutil.cpu_percent(interval=None, percpu=True),
}
def get_memory_info():
memory = psutil.virtual_memory()
return {
"total": memory.total,
"available": memory.available,
"used": memory.used,
"percent": memory.percent,
}
def get_disk_info():
disks = []
for partition in psutil.disk_partitions():
try:
usage = psutil.disk_usage(partition.mountpoint)
except (PermissionError, FileNotFoundError):
continue
disks.append(
{
"device": partition.device,
"mountpoint": partition.mountpoint,
"fstype": partition.fstype,
"total": usage.total,
"used": usage.used,
"free": usage.free,
"percent": usage.percent,
}
)
return disks
def init_process_cpu_percent():
for process in psutil.process_iter():
try:
process.cpu_percent(interval=None)
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
def get_top_processes(limit=5):
processes = []
for process in psutil.process_iter(["pid", "name", "cpu_percent", "memory_percent"]):
try:
info = process.info
processes.append(
{
"pid": info["pid"],
"name": info["name"] or "",
"cpu_percent": info["cpu_percent"] or 0.0,
"memory_percent": info["memory_percent"] or 0.0,
}
)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
continue
return sorted(processes, key=lambda item: item["cpu_percent"], reverse=True)[:limit]
def print_separator():
print("-" * 80)
def print_system_status():
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cpu = get_cpu_info()
memory = get_memory_info()
disks = get_disk_info()
top_processes = get_top_processes(TOP_PROCESS_LIMIT)
print(f"Python psutil 系統(tǒng)監(jiān)控工具")
print(f"刷新時間:{now}")
print_separator()
print("CPU 信息")
print(f"物理核心數(shù):{cpu['physical_count']}")
print(f"邏輯核心數(shù):{cpu['logical_count']}")
print(f"CPU 總使用率:{cpu['percent']}%")
print(f"各核心使用率:{', '.join(str(item) + '%' for item in cpu['per_core'])}")
print_separator()
print("內(nèi)存信息")
print(f"內(nèi)存總量:{format_bytes(memory['total'])}")
print(f"已用內(nèi)存:{format_bytes(memory['used'])}")
print(f"可用內(nèi)存:{format_bytes(memory['available'])}")
print(f"內(nèi)存使用率:{memory['percent']}%")
print_separator()
print("磁盤信息")
for disk in disks:
print(
f"{disk['device']} "
f"掛載點={disk['mountpoint']} "
f"文件系統(tǒng)={disk['fstype']} "
f"總量={format_bytes(disk['total'])} "
f"已用={format_bytes(disk['used'])} "
f"剩余={format_bytes(disk['free'])} "
f"使用率={disk['percent']}%"
)
print_separator()
print(f"CPU 占用最高的前 {TOP_PROCESS_LIMIT} 個進程")
print(f"{'PID':<10}{'CPU%':<10}{'MEM%':<10}進程名稱")
for process in top_processes:
print(
f"{process['pid']:<10}"
f"{process['cpu_percent']:<10.1f}"
f"{process['memory_percent']:<10.2f}"
f"{process['name']}"
)
print_separator()
print(f"每 {REFRESH_INTERVAL} 秒刷新一次,按 Ctrl + C 停止監(jiān)控")
def main():
init_process_cpu_percent()
try:
while True:
clear_screen()
print_system_status()
time.sleep(REFRESH_INTERVAL)
except KeyboardInterrupt:
print("\n監(jiān)控已停止")
if __name__ == "__main__":
main()
運行腳本:
python system_monitor.py
如果是在 Linux 服務器上,也可以使用:
python3 system_monitor.py
運行后,終端會每隔 2 秒刷新一次系統(tǒng)狀態(tài)。
九、腳本擴展方向
這個腳本只是一個基礎版本,后續(xù)可以繼續(xù)擴展:
- 增加 CPU、內(nèi)存、磁盤閾值判斷
- 超過閾值后發(fā)送郵件、釘釘或企業(yè)微信告警
- 將監(jiān)控數(shù)據(jù)寫入 CSV、SQLite、MySQL 或 InfluxDB
- 增加網(wǎng)絡流量監(jiān)控
- 增加指定進程存活檢測
- 使用
argparse支持命令行參數(shù),例如刷新間隔、進程數(shù)量、告警閾值 - 配合
schedule、cron或 Windows 任務計劃程序?qū)崿F(xiàn)定時巡檢 - 封裝成 Flask/FastAPI 接口,做成 Web 監(jiān)控面板
例如,增加一個簡單的內(nèi)存告警判斷:
import psutil
memory = psutil.virtual_memory()
if memory.percent >= 80:
print(f"警告:當前內(nèi)存使用率過高,已達到 {memory.percent}%")
再比如,檢查某個關(guān)鍵進程是否存在:
import psutil
target_process = "nginx"
exists = False
for process in psutil.process_iter(["name"]):
try:
if target_process.lower() in (process.info["name"] or "").lower():
exists = True
break
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
if not exists:
print(f"警告:進程 {target_process} 未運行")
十、總結(jié)
psutil 是 Python 運維自動化中非常實用的系統(tǒng)監(jiān)控庫。它屏蔽了不同操作系統(tǒng)之間的差異,讓我們可以用統(tǒng)一的 Python 代碼獲取 CPU、內(nèi)存、磁盤和進程信息。
本文完成了一個簡易系統(tǒng)監(jiān)控工具,核心能力包括:
- 使用
psutil.cpu_percent()獲取 CPU 使用率 - 使用
psutil.virtual_memory()獲取內(nèi)存狀態(tài) - 使用
psutil.disk_usage()和psutil.disk_partitions()獲取磁盤空間 - 使用
psutil.process_iter()獲取進程信息 - 使用循環(huán)和清屏實現(xiàn)實時刷新
- 整合為一個完整可運行的系統(tǒng)監(jiān)控腳本
對于 Python 運維自動化學習者來說,這類腳本非常適合作為練手項目。它既能幫助理解系統(tǒng)資源指標,也能為后續(xù)開發(fā)巡檢工具、告警工具和監(jiān)控 Agent 打下基礎。
以上就是使用Python+psutil開發(fā)一個簡易系統(tǒng)監(jiān)控工具的詳細內(nèi)容,更多關(guān)于Python psutil系統(tǒng)監(jiān)控工具的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python中使用PyExecJS庫執(zhí)行JavaScript函數(shù)
Python在運行JavaScript函數(shù)時,需要用到外部庫來執(zhí)行JavaScript,本文主要介紹了Python中使用PyExecJS庫執(zhí)行JavaScript函數(shù),具有一定的參考價值,感興趣的可以了解一下2024-04-04
python判斷一個數(shù)是否能被另一個整數(shù)整除的實例
今天小編就為大家分享一篇python判斷一個數(shù)是否能被另一個整數(shù)整除的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
pycharm如何實現(xiàn)跨目錄調(diào)用文件
這篇文章主要介紹了pycharm如何實現(xiàn)跨目錄調(diào)用文件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-02-02
使用Flask-Cache緩存實現(xiàn)給Flask提速的方法詳解
這篇文章主要介紹了使用Flask-Cache緩存實現(xiàn)給Flask提速的方法,結(jié)合實例形式詳細分析了Flask-Cache的安裝、配置及緩存使用相關(guān)操作技巧,需要的朋友可以參考下2019-06-06
使用OpenCV實現(xiàn)鼠標事件回調(diào)功能并繪制圖形
這篇文章主要為大家詳細介紹了如何使用OpenCV實現(xiàn)鼠標事件回調(diào)功能,并通過鼠標操作在圖像上繪制圓圈和矩形,感興趣的小伙伴可以了解下2024-11-11
Python中號稱神仙的六個內(nèi)置函數(shù)詳解
這篇文章主要介紹了Python中號稱神仙的六個內(nèi)置函數(shù),今天分享的這6個內(nèi)置函數(shù),在使用?Python?進行數(shù)據(jù)分析或者其他復雜的自動化任務時非常方便,需要的朋友可以參考下2022-05-05

