3 Star 6 Fork 1

wy3552128 / Nmonpy-NonGUI

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
nmonpy1.3.py 24.26 KB
一键复制 编辑 原始数据 按行查看 历史
#coding:utf-8
#python 3.8 版本退回到了3.4,因为高版本的python编译成exe后在低版本的操作系统上运行不了
__AUTHOR__ = '王勇'
version = 1.3
import glob
import os
import csv
import datetime
import time
class Nmonpy(object):
'''
【脚本功能描述】:
1、批量读入nmon文件,支持linux、aix平台下生成的nmon文件
2、对nmon文件按各性能指标进行逐个分析:主要是CPU利用率、内存利用率、磁盘IO、网络大小,生成一个总的测试汇总结果
3、同时针对各个nmon文件,还会生成对应的CSV分析结果,根据采样点输出结果值,更好的了解测试过程服务器性能变化情况,方便性能优化
4、根据情况,测试工程师可自行通过CSV结果绘制折线图
【使用方法描述】:
1、把本工具拷贝至nmon结果所在路径下,直接双机nmonpy.exe(已编译可执行文件),可批量生成CSV测试结果
【功能增强计划】:
1、增加log日志功能:在工具运行过程中打印运行日志
2、增加html折线图报表功能:根据对应的nmon文件,生成各自的html折线图报表
'''
def __init__(self):
'''
初始化数据
'''
self.nmon_dir = os.path.dirname(os.path.abspath(__file__)) # 与pytinstaller兼容
self.result_dir = self.nmon_dir + '\\Result' + str(datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
self.result_file = self.result_dir + '\服务器资源利用率统计表.csv'
def nmonfile(self, fileName):
'''
初始化分解nmon文件,主要获取nmon的监控次数和主机名称
:param :fileName
:return: nmontext, self.hostname, filenm, self.progname, self.starttime, self.interval
'''
fileText = open(fileName, 'r', encoding='utf8')
nmontext = fileText.readlines()
for line in nmontext:
if 'AAA,progname' in line:
self.progname = line.split(',')[2].split('\n')[0] #topas_nmon、aix
if 'AAA,host' in line:
self.hostname = line.split(',')[2]
if 'AAA,time,' in line:
self.starttime = line.split(',')[2].split('\n')[0] #开始监控时间点,linux nmon:10:23.26 aix nmon:10:23:26
if '.' in self.starttime:
self.starttime = self.starttime.split('.')[0] + ':10' #对linux nmon时间戳进行格式化,时间戳中.bug
if 'AAA,interval' in line:
self.interval = line.split(',')[2]
filenm = fileName.split('\\')[-1] #获取要分析的nmon文件名
fileText.close()
return nmontext, self.hostname, filenm, self.progname, self.starttime, self.interval
def CPU_AVG(self, nmontext, runtime, interval):
'''
计算CPU利用率100-idle
:param : nmontext, runtime, interval
:return: cpu_avg, cpu_points, TIME, cpu_user, cpu_sys, cpu_wait
'''
self.cpu_txt = []
cpu_user = []
cpu_sys = []
cpu_wait = []
cpu_points = []
cpu_value = 0.0
cpu_count = 0
TIME = []
starttime = str(runtime)
# 初始化TIME列,便于手动绘制折线图
TIME_format = datetime.datetime.strptime(starttime, '%H:%M:%S') #从nmon原始结果中分析得到nmon开始监控时间点
for line in nmontext:
#print(nmontext)
if ('CPU_ALL,T' in line) and ('PCPU_ALL,T' not in line) and ('SCPU_ALL,T' not in line): #排除aix nmon中的PCPU_ALL和SCPU_ALL列
self.cpu_txt.append(line)
for CPU in self.cpu_txt:
cpu_num = 100 - float(CPU.split(',')[5]) #100-idle,CPU利用率
cpu_points.append(format(cpu_num, ".2f")) #方便后期做曲线图,保留小数点后2位
cpu_value = cpu_value + cpu_num #CPU利用率合计,然后平均
#统计cpu各项list
cpu_user.append(CPU.split(',')[2]) # CPU user%
cpu_sys.append(CPU.split(',')[3]) # CPU sys%
cpu_wait.append(CPU.split(',')[4]) # CPU wait%
#初始化采样时间
time_end = (TIME_format + datetime.timedelta(seconds=int(interval))).strftime("%H:%M:%S") #timedelta()为增加或者减少时间,可以按hours、minutes、seconds来改变时间点
TIME.append(str(time_end))
starttime = TIME[-1] # 获取TIME list最后序列,然后进行时间初始化
TIME_format = datetime.datetime.strptime(starttime, '%H:%M:%S')
cpu_count = cpu_count + 1 #根据for循环次数获取实际监控采样次数
#计算CPU平均利用率
#print('cpu_count:', cpu_count)
cpu_avg = cpu_value / cpu_count
return cpu_avg, cpu_points, TIME, cpu_user, cpu_sys, cpu_wait
def MEM_Linux_AVG(self, nmontext):
'''
计算内存使用率
按照((mem_total - mem_free) + (swap_total - swap_free)) / (mem_total + swap_total) 公式计算
:param:nmontext
:return:mem_avg, mem_points, memtotal, memuse, swaptotal, swapuse, cache, buffer
'''
self.mem_txt = []
memtotal = []
memuse = []
swaptotal = []
swapuse = []
mem_points = []
cache = []
buffer = []
mem_use = 0.0
mem_count = 0
for line in nmontext:
if 'MEM,T' in line:
self.mem_txt.append(line)
#计算内存
for mem in self.mem_txt:
# print(float(mem.split(',')[9]))
mem_total = float(mem.split(',')[2]) # 获取nmon中物理内存总数
swap_total = float(mem.split(',')[5]) # 获取nmon中swap内存总数
mem_free = float(mem.split(',')[6]) # 获取nmon中物理内存空闲数
swap_free = float(mem.split(',')[9]) # 获取nmon中swap内存空闲数
mem_num = 100 * ((mem_total - mem_free) + (swap_total - swap_free)) / (mem_total + swap_total) #获取物理总、交换区总内存使用量
#print('内存单位(%):' + str(round(mem_num, 2))) #方便后期做曲线图
mem_points.append(format(mem_num, ".2f")) #方便后期做曲线图
mem_use = mem_use + mem_num
mem_count = mem_count + 1 #获取实际监控采样次数
memtotal.append(mem_total)
muse = mem_total - mem_free #计算物理内存使用
memuse.append(format(muse, ".2f"))
swaptotal.append(swap_total)
swapuse.append(swap_total - swap_free)
cache.append(mem.split(',')[11])
buffer.append(mem.split(',')[14])
#计算内存平均使用率
#print('mem_points', str(mem_points))
mem_avg = mem_use / mem_count
return mem_avg, mem_points, memtotal, memuse, swaptotal, swapuse, cache, buffer
def MEM_AIX_AVG(self, nmontext):
'''
计算内存使用率
按照((mem_total - mem_free) + (swap_total - swap_free)) / (mem_total + swap_total) 公式计算
:param:nmontext
:return:mem_avg, mem_points, memtotal, memuse, swaptotal, swapuse, cache, buffer
'''
self.mem_txt = []
self.mem_txtc = []
memtotal = []
memuse = []
space_total = []
space_use = []
mem_points = []
FScache = []
mem_use = 0.0
mem_count = 0
for line in nmontext:
if 'MEM,T' in line:
self.mem_txt.append(line)
#计算内存
for mem in self.mem_txt:
# print(float(mem.split(',')[9]))
mem_total = float(mem.split(',')[6]) # 获取nmon中物理内存总数
swap_total = float(mem.split(',')[7]) # 获取nmon中swap内存总数
mem_free = float(mem.split(',')[4]) # 获取nmon中物理内存空闲数
swap_free = float(mem.split(',')[5]) # 获取nmon中swap内存空闲数
mem_num = 100 * ((mem_total - mem_free) + (swap_total - swap_free)) / (mem_total + swap_total) #获取物理总、交换区总内存使用量
#print('内存单位(%):' + str(round(mem_num, 2))) #方便后期做曲线图
mem_points.append(format(mem_num, ".2f")) #方便后期做曲线图
mem_use = mem_use + mem_num
mem_count = mem_count + 1 #获取实际监控采样次数
memtotal.append(mem_total)
muse = mem_total - mem_free #计算物理内存使用
memuse.append(format(muse, ".2f"))
space_total.append(swap_total)
space_use.append(swap_total - swap_free)
#获取AIX 文件系统Cache内存占用率
for line in nmontext:
if 'MEMNEW,T' in line:
self.mem_txtc.append(line)
# 计算内存
for mem in self.mem_txtc:
FScache.append(float(mem.split(',')[3])) #FScache文件系统占用百分比
#计算内存平均使用率
#print('mem_points', str(mem_points))
mem_avg = mem_use / mem_count
return mem_avg, mem_points, memtotal, memuse, space_total, space_use, FScache
def DISK_AVG(self, nmontext):
'''
获取磁盘IO
:param:nmontext
:return:disk_avg, disk_points, disk_r_p, disk_w_p
'''
self.disk_txt = []
self.disk_busy = []
self.disk_w = []
self.disk_r = []
diskbusy = []
disk_points = []
disk_w_p = []
disk_r_p = []
disk_value = 0.0
disk_count = 0
for line in nmontext:
if 'DISKXFER,T' in line:
self.disk_txt.append(line)
if 'DISKREAD,T0' in line:
self.disk_r.append(line)
if 'DISKWRITE,T0' in line:
self.disk_w.append(line)
if 'DISKBUSY' in line:
self.disk_busy.append(line)
for disk in self.disk_txt:
#获取io
if 'DISKXFER,T0' in disk:
io_list = disk.split(',')[2:] #获取从第二个序列开始到最后一个序列的数值,然后这些数值相加,就是具体的IO值
#print(io_list)
io_num = sum(eval('['+(','.join(io_list))+']')) #list列表元素转为数字,然后相加
#print('磁盘IO单位(IO/s)' + io_num) #方便后期做曲线图
disk_points.append(format(io_num, ".2f")) #获取每个采样点的io数据
disk_value = disk_value + io_num #io合计,然后求平均值
disk_count = disk_count + 1 #获取实际监控采样次数
#获取每个采样点磁盘利用率%(多个磁盘只统计最大磁盘利用率%)
for disk_b in self.disk_busy:
if 'DISKBUSY,T' in disk_b:
diskbusy_end_list = disk_b.split(',')[-1].split('\n')[0] #把最后一个序列中的\n进行处理
diskbusy_new = disk_b.split(',')[2:-1] #取从第二个位置开始至倒数第二个位置的所有序列,形成新的列表,这样就排除了最后一个序列(最后一个带有\n)
diskbusy_new.append(diskbusy_end_list) #把最后一个序列加入到新的列表序列中
#print('diskbusy_new', diskbusy_new)
disk_int = list(map(eval, diskbusy_new))
diskbusy.append(max(disk_int)) #获取新序列中最大的序列值,即单个磁盘最大利用率
# 获取每个采样点disk read数据
for diskr in self.disk_r:
if 'DISKREAD,T0' in diskr:
disk_r = diskr.split(',')[2:]
disk_r_p.append(sum(eval('[' + (','.join(disk_r)) + ']'))) # 获取从第二个序列开始到最后一个序列的数值,然后这些数值相加
#获取每个采样点disk write数据
for diskw in self.disk_w:
if 'DISKWRITE,T0' in diskw:
disk_w = diskw.split(',')[2:]
disk_w_p.append(sum(eval('['+(','.join(disk_w))+']'))) #获取从第二个序列开始到最后一个序列的数值,然后这些数值相加
#获取磁盘平均IO
#print('disk_r_p', disk_r_p)
disk_avg = disk_value / disk_count
return disk_avg, disk_points, disk_r_p, disk_w_p, diskbusy
def NET_AVG(self, nmontext):
'''
获取网络读写大小
:param: nmontext
:return:net_avg, net_points, line_p, netread, netwrite
'''
self.net_txt = []
netread = []
netwrite = []
net_points = []
line_p = []
net_value = 0.0
net_count = 0
for line in nmontext:
if 'NET,T' in line:
self.net_txt.append(line)
for net in self.net_txt:
if 'NET' in net:
net_list = net.split(',')[2:] #获取最后两列的值
net_num = sum(eval('['+(','.join(net_list))+']')) #list列表元素转为数字,然后相加
#print('网络大小KB/s:', str(round(net_num, 2))) #方便后期做曲线图
net_points.append(format(net_num, ".2f"))
net_value = net_value + net_num
net_count = net_count + 1 #获取实际监控采样次数
line_p.append('') #分隔空列,做分割
nread = float(net.split(',')[2]) + float(net.split(',')[3])
netread.append(nread) #计算网络read
nwrite = float(net.split(',')[4]) + float(net.split(',')[5])
netwrite.append(nwrite) #计算网络write
#计算网络平均大小
net_avg = net_value / net_count #KB
return net_avg, net_points, line_p, netread, netwrite
def linuxnmon(self, nmontext, hostname, filenm, starttime, interval):
'''
汇总CPU、内存、磁盘IO、网络,以及其他详细资源使用情况,并输出分析结果
:param: nmontext, hostname, filenm, starttime, interval
:return:
'''
cpu, cpu_points, time, cpu_user, cpu_sys, cpu_wait = self.CPU_AVG(nmontext, starttime, interval)
mem, mem_points, memtotal, memuse, swaptotal, swapuse, cache, buffer = self.MEM_Linux_AVG(nmontext)
disk, disk_points, disk_r_p, disk_w_p, diskbusy = self.DISK_AVG(nmontext)
net, net_points, line_p, netread, netwrite = self.NET_AVG(nmontext)
#'%-30s' % str(filenm[0:35]) +
print('%-25s' % str(hostname.strip()[0:30]) + '%-12s' % str(format(cpu, ".2f")+ '%') + '%-15s' % str(format(mem, ".2f") + '%') + '%-15s' % str(format(disk, ".2f")) + '%-12s' % str(format(net, ".2f")))
print()
#生成各个nmon文件的结果汇总表
with open(self.result_file, 'a', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow([str(filenm), str(hostname.strip()), str(format(cpu, ".2f")), str(format(mem, ".2f")), str(format(disk, ".2f")), str(format(net, ".2f"))])
csvfile.close()
filenm_ana = filenm.split('.nmon')[0] #对分析结果名称进行初始化
#生成各个nmon文件的监控过程结果,可以手动在cvs结果中生成折线图
with open(self.result_dir + '\\' + str(filenm_ana) + '.csv', 'w', newline='') as csvfile:
w_clo = csv.writer(csvfile)
w_clo.writerow(['采样时间', 'CPU(%)', 'MEM(%)', 'Disk(io/s)', 'Net(KB/s)', '', 'cpu-us%', 'cpu-sys%', 'cpu-wait%', 'diskbusy%', 'diskread KB/s', 'diskwrite KB/s', 'memtotal KB/s', 'memuse KB/s', 'swaptotal KB/s', 'swapuse KB/s', 'cache KB/s', 'buffer KB/s', 'netread KB/s', 'netwrite KB/s'])
w_clo.writerows(zip(time, cpu_points, mem_points, disk_points, net_points, line_p, cpu_user, cpu_sys, cpu_wait, diskbusy, disk_r_p, disk_w_p, memtotal, memuse, swaptotal, swapuse, cache, buffer, netread, netwrite)) # 使用zip把TIME,CPU, MEM, DISK_IO, NET_KBS等4个list的数据按列存放,根据需要后面可加入其它列,比如cpu-usr、cpu-sys、disk-read、disk-write
w_clo.writerow('')
w_clo.writerow(['注意:请性能测试人员根据实际情况是否截头去尾,灵活自主的绘制折线图'])
csvfile.close()
def aixnmon(self, nmontext, hostname, filenm, starttime, interval):
'''
汇总CPU、内存、磁盘IO、网络,以及其他详细资源使用情况,并输出分析结果
:param: nmontext, hostname, filenm, starttime, interval
:return:
'''
cpu, cpu_points, time, cpu_user, cpu_sys, cpu_wait = self.CPU_AVG(nmontext, starttime, interval)
mem, mem_points, memtotal, memuse, spacetotal, space_use, FSCache = self.MEM_AIX_AVG(nmontext)
disk, disk_points, disk_r_p, disk_w_p, diskbusy = self.DISK_AVG(nmontext)
net, net_points, line_p, netread, netwrite = self.NET_AVG(nmontext)
print('%-25s' % str(hostname.strip()[0:30]) + '%-12s' % str(format(cpu, ".2f") + '%') + '%-15s' % str(
format(mem, ".2f") + '%') + '%-15s' % str(format(disk, ".2f")) + '%-12s' % str(format(net, ".2f")))
print()
# 生成各个nmon文件的结果汇总表
with open(self.result_file, 'a', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow([str(filenm), str(hostname.strip()), str(format(cpu, ".2f")), str(format(mem, ".2f")),
str(format(disk, ".2f")), str(format(net, ".2f"))])
csvfile.close()
filenm_ana = filenm.split('.nmon')[0] # 对分析结果名称进行初始化
# 生成各个nmon文件的监控过程结果,可以手动在cvs结果中生成折线图
with open(self.result_dir + '\\' + str(filenm_ana) + '.csv', 'w', newline='') as csvfile:
w_clo = csv.writer(csvfile)
w_clo.writerow(
['采样时间', 'CPU(%)', 'MEM(%)', 'Disk(io/s)', 'Net(KB/s)', '', 'cpu-us%', 'cpu-sys%', 'cpu-wait%',
'diskbusy%', 'diskread KB/s', 'diskwrite KB/s', 'mem total KB/s', 'mem use KB/s', 'Space total KB/s',
'Space use KB/s', 'FScache(%)', 'netread KB/s', 'netwrite KB/s'])
w_clo.writerows(
zip(time, cpu_points, mem_points, disk_points, net_points, line_p, cpu_user, cpu_sys, cpu_wait,
diskbusy, disk_r_p, disk_w_p, memtotal, memuse, spacetotal, space_use, FSCache, netread,
netwrite)) # 使用zip把TIME,CPU, MEM, DISK_IO, NET_KBS等4个list的数据按列存放,根据需要后面可加入其它列,比如cpu-usr、cpu-sys、disk-read、disk-write
w_clo.writerow('')
w_clo.writerow(['注意:请性能测试人员根据实际情况是否截头去尾,灵活自主的绘制折线图'])
csvfile.close()
def no_nmon(self):
'''
找不到nmon文件时打印界面
:return:
'''
time.sleep(0.5)
print('''
==================================================
+ +
+ 欢迎使用(HXB内部版本)- 技术测试室 +
+ +
==================================================
''')
time.sleep(1)
print('\n 当前路径:' + self.nmon_dir)
print('\n“Nmonpy正在寻找nmon文件,请稍等”\n')
print(' ......\n')
time.sleep(2)
print(' ......\n')
time.sleep(2)
print(' “不要着急,正在努力中”\n')
print(' ......\n')
print(' ......\n')
time.sleep(2)
print(' ......\n')
print('\n “没有找到nmon文件”')
time.sleep(1)
print('\n “劳驾把Nmonpy部署到nmon结果路径下。”\n')
input('\n 按回车键 <enter> 退出')
#os._exit(0)
def ps(self, nmonnum, aixnum):
# 在总结果csv文件中增加说明
with open(self.result_file, 'a', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow([])
writer.writerow(['共发现 ' + str(nmonnum) + ' 个nmon文件,' + str(nmonnum - aixnum) + ' 个Linux版本、' + str(aixnum) + ' 个AIX版本'])
csvfile.close()
print()
print('\n“您好,nmonpy已完成分析。”\n\n')
print('“共发现 ' + str(nmonnum) + ' 个nmon文件,' + str(nmonnum - aixnum) + ' 个Linux版本、' + str(aixnum) + ' 个AIX版本。”\n')
# 打开分析结果文件夹,解决工具部署在盘符根目录下不能打开结果文件夹的问题C:\\Result
if ':\\\\' in self.result_dir:
resultdir = self.result_dir.replace(':\\\\', ':\\')
print('\n 结果目录:' + resultdir + '\n')
input('\n 按回车键 <enter>, 自动打开结果文件夹')
os.system('start explorer ' + resultdir)
else:
print('\n 结果目录:' + self.result_dir + '\n')
input('\n 按回车键 <enter>, 打开结果文件夹')
os.system('start explorer ' + self.result_dir)
time.sleep(3)
input('\n\n 再次按回车键 <enter> 退出')
def main(self):
nmonnum = 0
aixnum = 0
# 判断在执行目录下nmon文件是否存
nmons = os.listdir(self.nmon_dir)
for k in range(len(nmons)):
nmons[k] = os.path.splitext(nmons[k])[1]
# 提取文件夹内所有文件的后缀
if '.nmon' not in nmons:
self.no_nmon() #判断当前目录下是否存在nmon文件
else:
time.sleep(0.5)
print('''
==================================================
+ +
+ 欢迎使用(HXB内部版本)- 技术测试室 +
+ +
==================================================
''')
print('\n\n “nmonpy已发现目标,开始进行分析操作,请稍等。”\n\n')
time.sleep(0.3)
# 判断result目录是否存在,不存在则创建,用于存放分析后结果
if not os.path.exists(self.result_dir):
os.mkdir(self.result_dir)
# '%-28s' % '文件名称' +
print('%-16s' % '主机名称' + '%-10s' % 'CPU利用率%' + '%-10s' % '内存利用率%' + '%-10s' % '磁盘(IO/s)' + '%-10s' % '网络(KB/s)\n')
with open(self.result_file, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['文件名称', '主机名称', 'CPU利用率(%)', '内存利用率(%)', '磁盘IO(io/s)', '网络大小(KB/s)'])
csvfile.close()
# 对本地目录下的nmon文件进行统计,并判断是否为linux版本的nmon,然后挨个分析
for nmonname in glob.glob(self.nmon_dir + '\*.nmon'):
# nmonpath = nmonname.replace('\\', '/')
nmonnum = nmonnum + 1
# time.sleep(0.05)
if nmonnum > 0:
nmontext, hostname, filenm, progname, starttime, interval = self.nmonfile(nmonname)
# 判断是否为AIX版本nmon if (progname == 'topas_nmon') or ('aix' in progname):
if 'AAA,AIX' in nmontext[7]:
aixnum = aixnum + 1 # 记录aix nmon文件数量
self.aixnmon(nmontext, hostname, filenm, starttime, interval) # 对AIX nmon进行分析
else:
self.linuxnmon(nmontext, hostname, filenm, starttime, interval) # 对LINUX nmon进行分析
#总结
self.ps(nmonnum, aixnum)
print(' ') #Game Over
if __name__ == '__main__':
nmon = Nmonpy()
nmon.main()
Python
1
https://gitee.com/zhuquehxb/Nmonpy-NonGUI.git
git@gitee.com:zhuquehxb/Nmonpy-NonGUI.git
zhuquehxb
Nmonpy-NonGUI
Nmonpy-NonGUI
master

搜索帮助