1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zhuquehxb-Nmonpy-NonGUI

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
nmonpy-forLinux.py 17 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
wy3552128 Отправлено 03.12.2019 10:56 8917014
#coding:utf-8
#python 3.8
__AUTHOR__ = '王勇'
version = 1.0
import glob
import os
import csv
import datetime
import time
class Nmonpy(object):
'''
脚本功能描述:
1、读入nmon文件
2、对nmon文件按各性能指标进行逐个分析:主要是CPU利用率、内存利用率、磁盘IO、网络大小
linux系统测试较多,目前仅支持Linux版本的nmon文件,后期对nmon分析功能进行不断加强:
1、批量统计/执行自定义目录下的所有nmon文件
2、增加config参数配置,自定义nmon文件路径
3、增加log功能
4、增加报表曲线图功能
'''
def __init__(self):
'''
初始化数据
'''
# 初始化结果目录Result
self.result_dir = os.path.dirname(os.path.abspath(__file__)) + '\\Result\\' #与pytinstaller兼容
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].split('.')[0] + ':10' #开始监控时间点
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:
if 'CPU_ALL,T' in line:
self.cpu_txt.append(line)
for CPU in self.cpu_txt:
cpu_num = 100 - float(CPU.split(',')[5]) #100-idle,CPU利用率
#print('CPU单位(%):' + str(round(cpu_num, 2))) #方便后期做曲线图
#cpu_num1 = '%.2f' % cpu_num #保留小数点两位
#cpu_num1 = round(cpu_num, 2)
#cpu_num1 = format(cpu_num, ".2f")
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_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 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 main(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_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(nmon_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) + '-' + str(datetime.datetime.now().strftime('%Y%m%d%H%M%S')) + '.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()
if __name__ == '__main__':
nmonnum = 0
aixnum = 0
aixfile = ''
nmon = Nmonpy()
#初始化结果文件
nmon_dir = os.path.dirname(os.path.abspath(__file__)) #与pytinstaller兼容
#判断在执行目录下nmon文件是否存
nmons = os.listdir(nmon_dir)
for k in range(len(nmons)):
nmons[k] = os.path.splitext(nmons[k])[1]
#提取文件夹内所有文件的后缀,如果.nmon格式文件不存在,则直接退出程序
if '.nmon' not in nmons:
time.sleep(0.5)
print('\n“您好,欢迎使用。nmonpy正在寻找nmon文件,请小主稍等片刻”\n\n' + ' ......\n')
time.sleep(2)
print(' ......\n')
time.sleep(2)
print('“正在努力中”\n')
print(' ......\n')
print(' ......\n')
time.sleep(2)
print(' ......\n')
print('“抱歉,本路径下没有找到nmon结果文件,呜呼!”。\n \n“劳驾小主把nmonpy部署到nmon结果所在路径。当前路径:' + nmon_dir + ' ”')
time.sleep(1)
print('\n“没有找到nmon文件,程序稍后退出......”')
time.sleep(5)
os._exit(0) #直接退出程序,不抛出异常
else:
time.sleep(0.5)
print('\n“您好,欢迎使用。nmonpy已发现目标,开始对nmon文件进行分析,请稍等1-2秒。”\n\n')
time.sleep(0.3)
# 判断result目录是否存在,不存在则创建,用于存放分析后结果
if not os.path.exists(nmon_dir + '\Result'):
os.mkdir(nmon_dir + '\Result')
nmon_file = nmon_dir + '\Result' + '\ZGHXB-Nmon分析汇总-' + str(datetime.datetime.now().strftime('%Y%m%d_%H%M_%S')) + '.csv'
#'%-28s' % '文件名称' +
print('%-16s' % '主机名称' + '%-10s' % 'CPU利用率(%)' + '%-10s' % '内存利用率(%)' + '%-10s' % '磁盘(io/s)' + '%-10s' % '网络(KB/s)')
with open( nmon_file, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['文件名称', '主机名称', 'CPU利用率(%)', '内存利用率(%)', '磁盘IO(io/s)', '网络大小(KB/s)'])
csvfile.close()
#对本地目录下的nmon文件进行统计,并判断是否为linux版本的nmon,然后挨个执行nmon分析
for nmonname in glob.glob(nmon_dir + '\*.nmon'):
#nmonpath = nmonname.replace('\\', '/')
nmonnum = nmonnum + 1
time.sleep(0.1)
if nmonnum > 0:
nmontext, hostname, filenm, progname, starttime, interval = nmon.nmonfile(nmonname)
if 'AAA,AIX' in nmontext[7]: #判断是否为AIX版本nmon
#if (progname == 'topas_nmon') or ('aix' in progname): #判断是否为AIX版本nmon
aixnum = aixnum + 1 #记录aix nmon文件数量
aixfile = str(aixfile) + str(filenm) + ' ' #记录aix nmon文件名到一个字符串中
else:
nmon.main(nmontext, hostname, filenm, starttime, interval)
#在总结果csv文件中增加说明
with open(nmon_file, 'a', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow([])
writer.writerow([' ' + aixfile + ' 共 ' + str(aixnum) + ' 个AIX版本的nmon结果暂不支持分析。'])
writer.writerow([])
writer.writerow(['共发现 ' + str(nmonnum) + ' 个nmon结果,其中 ' + str(nmonnum - aixnum) + ' 个Linux版本nmon结果被分析。测试工程师可直接复制使用。'] )
csvfile.close()
print()
print('“共发现 ' + str(nmonnum) + ' 个nmon结果,其中 ' + str(nmonnum - aixnum) + ' 个Linux版本nmon结果被分析。” \n')
print('“您好,nmonpy已完成本次nmon分析工作。” \n\n 最终结果路径:' + nmon_dir + '\Result\n\n See You!' )
time.sleep(5)

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/zhuquehxb-Nmonpy-NonGUI.git
git@api.gitlife.ru:oschina-mirror/zhuquehxb-Nmonpy-NonGUI.git
oschina-mirror
zhuquehxb-Nmonpy-NonGUI
zhuquehxb-Nmonpy-NonGUI
master