import os
import psutil
import time
from pyecharts import options as opts
from pyecharts.charts import Line
import PySimpleGUI as sg
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
import ctypes
import sys
2主界面及功能设计
classScatterPlotGUI:def__init__(self):
self.loc_path = os.getcwd()
self.errorLog_path = os.path.join(self.loc_path,"errorLog")
self.fig_save_path_folder = os.path.join(self.loc_path,"ReportFile")
self.fig_save_path =""
self.process_names =""
self.running =False
self.delay =0
self.executor = ThreadPoolExecutor(max_workers=1)
sg.theme('BrownBlue')
self.win_main = sg.Window('getCpuAndMemory', self.main_layout(), font=("Times New Roman",15),size=(400,100))defmain_layout(self):# 程序主界面
layout_file =[]
file_frame =[[
sg.Text('ProcessName(exe):', font=("Times New Roman",9)),
sg.Input(key='-process_names-', size=(4,1), default_text="msedge.exe",justification='center',font=("Times New Roman",9), expand_x=True, enable_events=True),#
sg.Text('CountIntervals(s):', font=("Times New Roman",9)),
sg.Input(key='-delay-', size=(4,1), default_text="3", justification='center', font=("Times New Roman",9), expand_x=True, enable_events=True),#],[
sg.Button('On', key='-start-', size=(10,1), font=("Times New Roman",9), expand_x=True, disabled=False),
sg.Button('Off', key='-stop-', size=(10,1), font=("Times New Roman",9), expand_x=True, disabled=True),
sg.Button('EXIT', key='-EXIT-', font=("Times New Roman",9), expand_x=True),],]
layout_file.append([sg.Frame(layout=file_frame, title="getCpuAndMemory", expand_x=True, font=("Times New Roman",8))])return layout_file
defrun(self):ifnot os.path.exists(self.fig_save_path_folder):# fig_save_path_folder
os.mkdir(self.fig_save_path_folder)
time_path = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')whileTrue:##task_pool = ThreadPoolExecutor(max_workers=1)
event_main, value_main = self.win_main.Read()
self.fig_save_path = os.path.join(self.fig_save_path_folder, time_path)
self.process_names = value_main['-process_names-']
self.delay =int(value_main['-delay-'])if event_main in(sg.WINDOW_CLOSED,"-EXIT-"):breakelif event_main =='-process_names-':
self.win_main['-start-'].update(disabled=False)elif event_main =='-start-':ifnot os.path.exists(self.fig_save_path):
os.mkdir(self.fig_save_path)
self.start_accumulator()elif event_main =='-stop-':
self.stop_accumulator()defgetCpuAndMemory(self, process_names):# 存储内存和CPU占用数据的变量
total_memory =0
total_cpu =0# 获取指定进程的信息
pids = psutil.pids()for pid in pids:try:
p = psutil.Process(pid)if p.name()in process_names:# 获取进程的内存和CPU占用情况# process.memory_info()# rss: 该进程实际使用物理内存(包含共享库占用的全部内存,不包括共享内存和映射文件等)。# vms:该进程使用的虚拟内存总量。# uss: 进程的所有占用的私有物理内存大小,包括私有物理内存、共享内存和映射文件等。#mem = p.memory_info().rss / (1024 ** 2) # 单位:MB
mem = p.memory_full_info().uss /(1024**2)# 单位:MB #更准确
cpu = p.cpu_percent(interval=0.5)# 累加内存和CPU占用量
total_memory += mem
total_cpu += cpu
#print("==>>> processName:%s processStatus:%s processMememory:%.4f processCPU:%.4f <<<==" % (p.name(), p.status(), mem, cpu))except(psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess)as e:pass# except psutil.NoSuchProcess as e1:# #print("no process found with pid=&s" % pid)# print("@NoSuchProcess>>> ", e1)# pass# except psutil.AccessDenied as e2:# #print("no process found with pid=&s" % pid)# print("@AccessDenied>>> ", e2)# pass# except psutil.ZombieProcess as e3:# #print("no process found with pid=&s" % pid)# print("@ZombieProcess>>> ", e3)# passprint("==>>> %s processName:%s TotalMememory:%.4f TotalCPU:%.4f <<<=="%(time.strftime('%Y-%m-%d %H:%M:%S'), process_names, total_memory, total_cpu))# 判断目录下是否已存在 memory.txt 和 cpu.txt 文件
memory_txt = os.path.join(self.fig_save_path,'%s_memory.txt'%self.process_names[:-4])
cpu_txt = os.path.join(self.fig_save_path,'%s_cpu.txt'%self.process_names[:-4])ifnot os.path.isfile(memory_txt):withopen(memory_txt,'w')as f:passifnot os.path.isfile(cpu_txt):withopen(cpu_txt,'w')as f:pass
finalMemory ='%.3f'% total_memory
finalCPU ='%.3f'% total_cpu
# 将总的内存和CPU占用量写入文件, a表示追加数据withopen(memory_txt,'a')as f:
f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')}{finalMemory}\n")withopen(cpu_txt,'a')as f:
f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')}{finalCPU}\n")defgenerateCpuAndMemoryReport(self, process_names):try:while self.running:#获取内存和CPU数据
self.getCpuAndMemory(process_names)# 获取当前脚本所在的目录
memory_txt = os.path.join(self.fig_save_path,'%s_memory.txt'%self.process_names[:-4])
cpu_txt = os.path.join(self.fig_save_path,'%s_cpu.txt'%self.process_names[:-4])
memory_html = os.path.join(self.fig_save_path,'%s_memory_monitor_report.html'%self.process_names[:-4])
cpu_html = os.path.join(self.fig_save_path,'%s_cpu_monitor_report.html'%self.process_names[:-4])# 获取内存折线图需要绘制的数据信息
x =[]
y =[]withopen(memory_txt)as f:for line in f:
space_index = line.find(' ')if space_index !=-1:
data = line[space_index +1:]# 切片操作,保留空格之后的部分
time0, per = data.strip().split()
x.append(time0)
y.append(float(per))# 将字符串转换为浮点数
line =(
Line().add_xaxis(x).add_yaxis("", y, label_opts=opts.LabelOpts(is_show=False)).set_global_opts(title_opts=opts.TitleOpts(title="内存使用监控,单位:M")))
line.render(path=memory_html)# 获取cpu折线图需要绘制的数据信息
x =[]
y =[]withopen(cpu_txt)as f:for line in f:
space_index = line.find(' ')if space_index !=-1:
data = line[space_index +1:]# 切片操作,保留空格之后的部分
time1, per = data.strip().split()
x.append(time1)
y.append(float(per))# 将字符串转换为浮点数
line =(
Line().add_xaxis(x).add_yaxis("", y, label_opts=opts.LabelOpts(is_show=False)).set_global_opts(title_opts=opts.TitleOpts(title="cpu使用监控,单位:百分比")))
line.render(path=cpu_html)
time.sleep(self.delay)except Exception as e:print("@error>>> ", e)defclose(self):
self.win_main.close()
self.executor.shutdown(wait=True)defstart_accumulator(self):ifnot self.running:
self.running =True
self.win_main['-start-'].update(disabled=True)
self.win_main['-stop-'].update(disabled=False)
self.executor.submit(self.generateCpuAndMemoryReport, self.process_names)defstop_accumulator(self):if self.running:
self.running =False
self.win_main['-start-'].update(disabled=False)
self.win_main['-stop-'].update(disabled=True)print("------------------>-->>-->>> Execution stopped <<<--<<--<------------------")