Python psutil
上次修改时间 2024年9月16日
在本文中,我们将展示如何检索有关进程和系统利用率的信息。
psutil 是一个 Python 模块,它提供了一个简单的接口来检索有关正在运行的进程、系统用户、网络、磁盘等的各种信息。 它是系统监控和管理任务的强大工具。
psutil.Process().info()
方法用于检索有关特定进程的详细信息。 它返回一个字典,其中包含进程的各种属性,例如:
- pid - 进程ID
- ppid - 父进程ID
- name - 进程名称
- exe - 可执行文件路径
- cmdline - 用于启动进程的命令行参数
- status - 进程状态 (例如, 'running', 'sleeping', 'zombie')
- create_time - 进程创建时间
- user - 与进程关联的用户名
- nice - 进程优先级
- io_counters - I/O 计数器 (读取/写入字节, 系统调用)
- cpu_times - CPU 时间 (用户, 系统, 空闲等)
- memory_info - 内存使用信息 (RSS, VMS 等)
在示例中,我们使用 argparse
模块来解析命令行参数。
列出内存使用情况
该示例列出内存使用量高于给定 MB 值的进程。
main.py
import psutil import argparse parser = argparse.ArgumentParser() parser.add_argument('memory', help='memory value in MB') args = parser.parse_args() mem_limit = int(args.memory) * 1024 * 1024 p_it = psutil.process_iter(['name', 'memory_info']) large_mem_ps = [{'pid': p.pid, 'name': p.info['name'], 'mem': p.info['memory_info'].rss} for p in p_it if p.info['memory_info'].rss > mem_limit] for p in large_mem_ps: print(f'{p['pid']} {p['name']} {(p['mem'] / (1024 * 1024)):.2f}')
该程序接受一个位置参数:内存值,单位为 MB。
p_it = psutil.process_iter(['name', 'memory_info'])
process_iter
函数返回一个生成器,为所有正在运行的进程生成一个 Process 实例。 我们从生成的数据中挑选出进程的名称和 memory_info 属性。
large_mem_ps = [{'pid': p.pid, 'name': p.info['name'], 'mem': p.info['memory_info'].rss} for p in p_it if p.info['memory_info'].rss > mem_limit]
我们选择所有使用内存超过我们限制的进程。
for p in large_mem_ps: print(f'{p['pid']} {p['name']} {(p['mem'] / (1024 * 1024)):.2f}')
我们遍历列表并打印数据。
CPU 使用率
cpu_times
属性提供有关进程消耗的 CPU 时间的信息。
main.py
import psutil processes = [ {'pid': p.pid, 'name': p.info['name'], 'sum_cpu_t': sum(p.info['cpu_times'])} for p in psutil.process_iter(['name', 'cpu_times']) ] sorted_ps = sorted(processes, key=lambda p: p['sum_cpu_t']) # print the last five for e in sorted_ps[-5:]: print(f'pid: {e['pid']} name: {e['name']} cpu time: {e['sum_cpu_t']}')
该程序按 CPU 使用率列出前五个进程。
processes = [ {'pid': p.pid, 'name': p.info['name'], 'sum_cpu_t': sum(p.info['cpu_times'])} for p in psutil.process_iter(['name', 'cpu_times']) ]
我们获取一个进程列表,包括它们的进程 ID、名称和 CPU 使用率。
sorted_ps = sorted(processes, key=lambda p: p['sum_cpu_t'])
我们按其 CPU 时间总和(用户 + 系统)对进程进行排序。
# print the last five for e in sorted_ps[-5:]: print(f'pid: {e['pid']} name: {e['name']} cpu time: {e['sum_cpu_t']}')
由于列表按升序排序,我们打印最后五个进程。
检查进程的日志文件
open_files
属性返回与该进程关联的文件描述符列表。 每个文件描述符表示为一个元组,包含以下信息:
- path - 文件或设备的路径
- fd - 文件描述符编号
- position - 文件中的当前位置
- flags - 指示文件访问模式的标志(读取、写入等)
main.py
import psutil for p in psutil.process_iter(['name', 'open_files']): for file in p.info['open_files'] or []: if file.path.endswith('.log'): print(f"{p.pid:<5} {p.info['name']:<20} {file.path}")
该程序列出所有已打开日志文件的进程。
列出进程
以下脚本列出进程。 我们使用第三方 rich 库在控制台上的表格中显示输出。
main.py
import psutil import argparse from datetime import datetime from rich import box from rich.console import Console from rich.table import Table from datetime import date def parse_arguments(): parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-a', '--all', action='store_true', help='show all processes') group.add_argument('-n', '--name', help='show info about process name') args = parser.parse_args() return args.all, args.name def list_process(name): now = f'{date.today()}' table = Table(title=f'Process', box=box.MINIMAL, caption=now, caption_justify='left') table.add_column('id', style='cyan') table.add_column('process name', style='grey69') table.add_column('username') table.add_column('create time', style='blue') table.add_column('memory', style='green') process_count = 0 for p in psutil.process_iter(): if name in p.name().lower(): ctime = datetime.fromtimestamp(p.create_time()) memory_percent = p.memory_percent() table.add_row(f'{p.pid}', p.name(), p.username(), ctime.isoformat(), f'{memory_percent:.2f}') process_count += 1 if process_count > 0: console = Console() console.print(table, justify='center') else: print('no such process found') def list_all_processes(): now = f'{date.today()}' table = Table(title='Processes', box=box.MINIMAL, caption=now, caption_justify='left') table.add_column('id', style='cyan') table.add_column('process name', style='grey69') pnames = [] for p in psutil.process_iter(): pnames.append(p.name()) table.add_row(f'[bold]{p.pid}', f'[bold]{p.name()}') console = Console() console.print(table, justify='center') print(len(pnames), 'processes') print(len(set(pnames)), 'apps') all_f, name = parse_arguments() if all_f: list_all_processes() elif name: list_process(name)
该脚本接受两个选项:-a/-all
列出所有进程,而 -n/--name
显示有关特定进程的信息。 这些选项是互斥的。
来源
在本文中,我们使用了 Python 中的谓词。
作者
列出所有 Python 教程。