让GPT-4使用python写一个进程监控工具
- 给出一些提示进行多次的交互,最后给出完整的代码,进行调试与少量修改即可运行,实现了需求的功能!强到炸裂!!
提示1:
我需要实现一个监控工具,输入一个进程号为pid,每间隔internal时间采集一次监控数据,监控的进程信息为物理内存,虚拟内存,cpu使用率,显存占用,gpu使用率,该进程持有的句柄数,该进程的线程数量,请你封装成函数,将进程id作为参数,每次返回一条采样的数据,数据内容为 采样的时间(格式为“%Y/%m/%d %HH:%MM:%SS”),物理内存,虚拟内存,cpu使用率,显存占用,gpu使用率,句柄数,线程数量,请你用python代码实现
其他功能说明:
1. 支持设置参数运行多长时间,比如运行10分钟停止
2. 保存中间数据,每采集10次将结果写入文件一次
3. 将结果数据保存到Excel文件中,要求包含表头,并在文件中绘制各种监控数据随时间变化的折线图
4. 增加一个main函数,将进程id,数据采样的间隔时间,监控运行的总时间,保存的Excel文件名称作为参数,如果用户输入不符合参数要求则进行提示
5. 将每个监控项绘制成折线图,每个监控项保存到一个sheet中,第一个sheet保存原始采样的监控数据
6. 将表头设置成合适的宽度
7. 支持Ctrl+C时正常退出并保存已采集的数据
8. 支持进程被kill或崩溃退出后监控程序保存已采集数据并退出
9. 默认需要的psutil/openpyxl等库已安装
回答:...
-- 因为回答可能太长了,没有回答完整继续提示
提示2:
请给出完整实现,不要简化的,并且请输出完整,考虑使用类对功能进行封装
提示3:
结果不完整,请继续
提示4:
仅修改一下main函数,将各参数作为命令行参数输入,不需要交互的输入,命令行参数缺失时进行提示
环境说明
- 运行需要使用 pip install psutil openpyxl pynvml 安装这三个依赖库,且切到root权限
- 访问GPT4需要歪王:https://chat.openai.com/chat?model=gpt-4
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
File description: 这是一个GPU进程资源使用情况监控工具,由GPT-4生成,人工进行了check以及少量的修改
A monitor for Process use GPU.
@author: doothink
@email:
@copyright: Copyright (c) 2023 doothink. All rights reserved.
@license: MIT License
"""
import time
import datetime
import os
import signal
import sys
import psutil
import openpyxl
import pynvml as nvml
from openpyxl.chart import LineChart, Reference
from openpyxl.utils import get_column_letter
class ProcessMonitor:
def __init__(self, pid, interval, duration, file_name):
self.pid = pid
self.interval = interval
self.duration = duration
self.file_name = file_name
self.data_samples = []
def monitor_process(self):
try:
process = psutil.Process(self.pid)
mem_info = process.memory_info()
cpu_percent = process.cpu_percent(self.interval)
nvml.nvmlInit()
handle = nvml.nvmlDeviceGetHandleByIndex(0)
gpu_memory = nvml.nvmlDeviceGetMemoryInfo(handle)
gpu_util = nvml.nvmlDeviceGetUtilizationRates(handle)
# Replace with a function to get GPU usage
gpu_mem = gpu_memory.used / (1024 * 1024 )
gpu_percent = gpu_util.gpu
num_handles = process.num_fds()
num_threads = process.num_threads()
rss_used = mem_info.rss / (1024 * 1024 )
vms_used = mem_info.vms / (1024 * 1024 )
return datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"), rss_used, vms_used, cpu_percent, gpu_mem,\
gpu_percent, num_handles, num_threads
except psutil.NoSuchProcess:
print("No such process with PID:", self.pid)
return None
def save_data_to_excel(self):
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "Raw Data"
headers = ["Timestamp", "Physical Memory", "Virtual Memory", "CPU Usage", "GPU Memory", "GPU Usage", "Handles", "Threads"]
for col_num, header in enumerate(headers, 1):
col_letter = get_column_letter(col_num)
ws.column_dimensions[col_letter].width = 15
ws.cell(row=1, column=col_num).value = header
for row_num, row in enumerate(self.data_samples, 2):
for col_num, value in enumerate(row, 1):
ws.cell(row=row_num, column=col_num).value = value
for col_num, header in enumerate(headers[1:], 2):
chart = LineChart()
chart.title = header
chart.x_axis.title = "Timestamp"
chart.y_axis.title = header
data_ref = Reference(ws, min_col=col_num, min_row=1, max_col=col_num, max_row=len(self.data_samples) + 1)
cats = Reference(ws, min_col=1, min_row=2, max_row=len(self.data_samples) + 1)
chart.add_data(data_ref, titles_from_data=True)
chart.set_categories(cats)
chart_ws = wb.create_sheet(title=header)
chart_ws.add_chart(chart, "A1")
wb.save(self.file_name)
def exit_handler(self, signal, frame):
self.save_data_to_excel()
sys.exit(0)
def run(self):
signal.signal(signal.SIGINT, self.exit_handler)
signal.signal(signal.SIGTERM, self.exit_handler)
start_time = time.time()
while time.time() - start_time < self.duration:
sample = self.monitor_process()
if sample:
self.data_samples.append(sample)
if len(self.data_samples) % 20 == 0:
self.save_data_to_excel()
else:
break
time.sleep(self.interval)
self.save_data_to_excel()
import argparse
def parse_arguments(need_tips = False):
parser = argparse.ArgumentParser(description="Process Monitor")
parser.add_argument("-p", "--pid", type=int, required=True, help="进程ID")
parser.add_argument("-i", "--interval", type=float, required=True, help="数据采样的间隔时间(秒)")
parser.add_argument("-d", "--duration", type=int, required=True, help="监控运行的总时间(秒)")
parser.add_argument("-f", "--file_name", type=str, required=True, help="保存的Excel文件名称(包含扩展名.xlsx)")
if need_tips:
parser.print_usage()
parser.print_help()
return parser.parse_args()
if __name__ == "__main__":
args = parse_arguments(need_tips = len(sys.argv)!=9)
pid = args.pid
interval = args.interval
duration = args.duration
file_name = args.file_name
monitor = ProcessMonitor(pid, interval, duration, file_name)
monitor.run()