psutil(process and system utilities)是一个跨平台库,用于获取系统运行进程和系统利用率(CPU、内存、磁盘、网络等)的信息。

主要功能

  1. 系统监控:CPU、内存、磁盘、网络使用情况
  2. 进程管理:查看、管理、监控系统进程
  3. 跨平台支持:Windows、Linux、macOS、FreeBSD等

安装

pip install psutil

基本用法

1. 系统信息概览

import psutil
import datetime

# 获取系统启动时间
boot_time = psutil.boot_time()
print(f"系统启动时间: {datetime.datetime.fromtimestamp(boot_time)}")

# 获取当前登录用户
users = psutil.users()
for user in users:
    print(f"用户: {user.name}, 终端: {user.terminal}, 登录时间: {datetime.datetime.fromtimestamp(user.started)}")

2. CPU 监控

import psutil

# CPU 使用率
cpu_percent = psutil.cpu_percent(interval=1)
print(f"CPU 总使用率: {cpu_percent}%")

# 每个 CPU 核心的使用率
cpu_percent_per_core = psutil.cpu_percent(interval=1, percpu=True)
for i, usage in enumerate(cpu_percent_per_core):
    print(f"CPU 核心 {i} 使用率: {usage}%")

# CPU 统计信息
cpu_times = psutil.cpu_times()
print(f"用户模式时间: {cpu_times.user} 秒")
print(f"系统模式时间: {cpu_times.system} 秒")
print(f"空闲时间: {cpu_times.idle} 秒")

# CPU 频率
cpu_freq = psutil.cpu_freq()
print(f"当前频率: {cpu_freq.current} MHz")
print(f"最小频率: {cpu_freq.min} MHz")
print(f"最大频率: {cpu_freq.max} MHz")

# CPU 核心数量
print(f"物理核心数: {psutil.cpu_count(logical=False)}")
print(f"逻辑核心数: {psutil.cpu_count(logical=True)}")

3. 内存监控

import psutil

# 虚拟内存信息
virtual_mem = psutil.virtual_memory()
print(f"总内存: {virtual_mem.total / (1024**3):.2f} GB")
print(f"可用内存: {virtual_mem.available / (1024**3):.2f} GB")
print(f"已用内存: {virtual_mem.used / (1024**3):.2f} GB")
print(f"内存使用率: {virtual_mem.percent}%")

# 交换内存信息
swap_mem = psutil.swap_memory()
print(f"交换内存总数: {swap_mem.total / (1024**3):.2f} GB")
print(f"交换内存使用率: {swap_mem.percent}%")

4. 磁盘监控

import psutil

# 磁盘分区信息
partitions = psutil.disk_partitions()
for partition in partitions:
    print(f"设备: {partition.device}")
    print(f"挂载点: {partition.mountpoint}")
    print(f"文件系统: {partition.fstype}")
    
    # 磁盘使用情况
    try:
        usage = psutil.disk_usage(partition.mountpoint)
        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}%")
    except PermissionError:
        print("权限不足,无法访问")
    print("---")

# 磁盘 I/O 统计
disk_io = psutil.disk_io_counters()
print(f"读取次数: {disk_io.read_count}")
print(f"写入次数: {disk_io.write_count}")
print(f"读取字节: {disk_io.read_bytes / (1024**2):.2f} MB")
print(f"写入字节: {disk_io.write_bytes / (1024**2):.2f} MB")

5. 网络监控

import psutil

# 网络接口信息
net_io = psutil.net_io_counters()
print(f"发送字节: {net_io.bytes_sent / (1024**2):.2f} MB")
print(f"接收字节: {net_io.bytes_recv / (1024**2):.2f} MB")
print(f"发送包数: {net_io.packets_sent}")
print(f"接收包数: {net_io.packets_recv}")

# 网络连接信息
connections = psutil.net_connections()
for conn in connections[:5]:  # 显示前5个连接
    print(f"协议: {conn.type}")
    print(f"本地地址: {conn.laddr}")
    print(f"远程地址: {conn.raddr}")
    print(f"状态: {conn.status}")
    print("---")

# 网络接口统计
net_if_stats = psutil.net_if_stats()
for interface, stats in net_if_stats.items():
    print(f"接口: {interface}")
    print(f"是否启用: {stats.isup}")
    print(f"速度: {stats.speed} Mbps")
    print("---")

进程管理

1. 获取进程列表

import psutil

# 获取所有进程ID
pids = psutil.pids()
print(f"当前进程数: {len(pids)}")

# 遍历所有进程
for proc in psutil.process_iter(['pid', 'name', 'username']):
    try:
        proc_info = proc.info
        print(f"PID: {proc_info['pid']}, 名称: {proc_info['name']}, 用户: {proc_info['username']}")
    except (psutil.NoSuchProcess, psutil.AccessDenied):
        pass

2. 进程详细信息

import psutil

# 获取当前进程
current_process = psutil.Process()

# 进程基本信息
print(f"进程ID: {current_process.pid}")
print(f"进程名称: {current_process.name()}")
print(f"进程状态: {current_process.status()}")
print(f"创建时间: {current_process.create_time()}")
print(f"工作目录: {current_process.cwd()}")
print(f"可执行文件路径: {current_process.exe()}")

# 进程资源使用
print(f"CPU 使用率: {current_process.cpu_percent()}%")
print(f"内存使用率: {current_process.memory_percent()}%")
memory_info = current_process.memory_info()
print(f"内存使用: {memory_info.rss / (1024**2):.2f} MB")

# 进程打开的文件
try:
    open_files = current_process.open_files()
    for file in open_files[:3]:  # 显示前3个文件
        print(f"打开文件: {file.path}")
except psutil.AccessDenied:
    print("无权限查看打开的文件")

# 进程网络连接
try:
    connections = current_process.connections()
    for conn in connections:
        print(f"连接: {conn.laddr} -> {conn.raddr}")
except psutil.AccessDenied:
    print("无权限查看网络连接")

3. 进程管理操作

import psutil
import time

def monitor_process(pid):
    try:
        process = psutil.Process(pid)
        
        while process.is_running():
            # 获取进程信息
            cpu_percent = process.cpu_percent()
            memory_percent = process.memory_percent()
            memory_usage = process.memory_info().rss / (1024**2)
            
            print(f"PID: {pid}, CPU: {cpu_percent}%, 内存: {memory_percent}% ({memory_usage:.2f} MB)")
            time.sleep(2)
            
    except psutil.NoSuchProcess:
        print(f"进程 {pid} 不存在")

# 查找特定进程
def find_process_by_name(name):
    for proc in psutil.process_iter(['name', 'pid']):
        if proc.info['name'] == name:
            return proc.info['pid']
    return None

# 示例:监控 Python 进程
python_pid = find_process_by_name('python.exe')
if python_pid:
    monitor_process(python_pid)

高级功能

1. 系统监控仪表板

import psutil
import time
import os

def system_dashboard():
    while True:
        os.system('cls' if os.name == 'nt' else 'clear')  # 清屏
        
        # CPU 信息
        cpu_percent = psutil.cpu_percent(interval=1)
        cpu_freq = psutil.cpu_freq()
        
        # 内存信息
        memory = psutil.virtual_memory()
        
        # 磁盘信息
        disk = psutil.disk_usage('/')
        
        # 网络信息
        net_io = psutil.net_io_counters()
        
        print("=== 系统监控仪表板 ===")
        print(f"CPU 使用率: {cpu_percent}%")
        print(f"CPU 频率: {cpu_freq.current} MHz")
        print(f"内存使用: {memory.percent}% ({memory.used/(1024**3):.1f}GB/{memory.total/(1024**3):.1f}GB)")
        print(f"磁盘使用: {disk.percent}% ({disk.used/(1024**3):.1f}GB/{disk.total/(1024**3):.1f}GB)")
        print(f"网络: 上传 {net_io.bytes_sent/(1024**2):.1f}MB, 下载 {net_io.bytes_recv/(1024**2):.1f}MB")
        print("=" * 30)
        
        time.sleep(5)

# 运行监控仪表板
# system_dashboard()

2. 进程资源监控器

import psutil
import time
from collections import defaultdict

class ProcessMonitor:
    def __init__(self):
        self.history = defaultdict(list)
    
    def monitor_processes(self, duration=60, interval=2):
        """监控进程资源使用情况"""
        end_time = time.time() + duration
        
        while time.time() < end_time:
            timestamp = time.time()
            
            for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
                try:
                    info = proc.info
                    pid = info['pid']
                    
                    # 更新进程信息
                    self.history[pid].append({
                        'timestamp': timestamp,
                        'name': info['name'],
                        'cpu': info['cpu_percent'],
                        'memory': info['memory_percent']
                    })
                    
                except (psutil.NoSuchProcess, psutil.AccessDenied):
                    continue
            
            time.sleep(interval)
    
    def get_top_processes(self, metric='cpu', top_n=5):
        """获取资源使用最高的进程"""
        if not self.history:
            return []
        
        # 计算平均使用率
        avg_usage = {}
        for pid, records in self.history.items():
            if records:
                values = [r[metric] for r in records]
                avg_usage[pid] = sum(values) / len(values)
        
        # 排序并返回前N个
        sorted_pids = sorted(avg_usage.items(), key=lambda x: x[1], reverse=True)
        
        top_processes = []
        for pid, usage in sorted_pids[:top_n]:
            name = self.history[pid][0]['name']
            top_processes.append({'pid': pid, 'name': name, 'usage': usage})
        
        return top_processes

# 使用示例
monitor = ProcessMonitor()
monitor.monitor_processes(duration=30)  # 监控30秒

print("CPU 使用最高的进程:")
for proc in monitor.get_top_processes('cpu', 3):
    print(f"{proc['name']} (PID: {proc['pid']}): {proc['usage']:.1f}%")

3. 系统告警系统

import psutil
import time
import smtplib
from email.mime.text import MimeText

class SystemAlert:
    def __init__(self, thresholds):
        self.thresholds = thresholds
        self.alerts_sent = set()
    
    def check_system_health(self):
        alerts = []
        
        # 检查 CPU
        cpu_percent = psutil.cpu_percent(interval=1)
        if cpu_percent > self.thresholds['cpu']:
            alerts.append(f"CPU 使用率过高: {cpu_percent}%")
        
        # 检查内存
        memory = psutil.virtual_memory()
        if memory.percent > self.thresholds['memory']:
            alerts.append(f"内存使用率过高: {memory.percent}%")
        
        # 检查磁盘
        disk = psutil.disk_usage('/')
        if disk.percent > self.thresholds['disk']:
            alerts.append(f"磁盘使用率过高: {disk.percent}%")
        
        return alerts
    
    def monitor(self):
        while True:
            alerts = self.check_system_health()
            
            for alert in alerts:
                alert_hash = hash(alert)
                if alert_hash not in self.alerts_sent:
                    print(f"告警: {alert}")
                    # self.send_alert(alert)  # 发送邮件告警
                    self.alerts_sent.add(alert_hash)
            
            time.sleep(60)  # 每分钟检查一次

# 使用示例
thresholds = {
    'cpu': 80,      # CPU 使用率阈值 80%
    'memory': 85,   # 内存使用率阈值 85%
    'disk': 90      # 磁盘使用率阈值 90%
}

alert_system = SystemAlert(thresholds)
# alert_system.monitor()

注意事项

  1. 权限问题:某些信息需要管理员/root权限才能访问
  2. 性能影响:频繁调用psutil可能对系统性能有轻微影响
  3. 跨平台差异:不同操作系统返回的信息可能略有不同
  4. 异常处理:进程可能在任何时候结束,需要处理NoSuchProcess异常

psutil 是一个功能强大的系统监控库,适用于系统监控、性能分析、资源管理等场景。