think more more

导航

GPU进程资源使用情况监控工具

让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函数,将各参数作为命令行参数输入,不需要交互的输入,命令行参数缺失时进行提示

环境说明

  1. 运行需要使用 pip install psutil openpyxl pynvml 安装这三个依赖库,且切到root权限
  2. 访问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()


posted on 2023-03-25 15:21  duothink  阅读(311)  评论(1编辑  收藏  举报