1 !/usr/bin/env python 2 # encoding: utf-8 3 from __future__ import division 4 import codecs 5 import os 6 import platform 7 import psutil 8 import re 9 import socket 10 import sys 11 import time 12 import datetime 13 import json 14 import threading 15 import xlrd 16 import xlwt 17 from xlutils.copy import copy 18 from loadrunner.common.logger import * 19 try: 20 import platform 21 if platform.system() == 'Windows': 22 import wmi 23 except Exception as e: 24 LOG_DEBUG(e) 25 def release(obj=r'C:ProgramDataSangforEDRSAVcache'): 26 try: 27 if os.path.isfile(obj): 28 return 29 cmd = 'cacls ' + obj + '*.* /g everyone:f' 30 print(cmd) 31 # os.system(cmd) 32 p = os.popen(cmd, "w") # auto confirm 33 p.write('y ') 34 subobjs = os.path.os.listdir(obj) 35 if subobjs == []: 36 return 37 else: 38 for temp in subobjs: 39 tempobj = os.path.join(obj, temp) 40 release(tempobj) 41 except Exception as e: 42 LOG_ERROR(e) 43 44 45 def winrar(opr, tar_name, compressed_files, winrar_exe=r'"C:Program FilesWinRARWinRAR.exe"'): 46 """ 47 win解压缩 48 :param opr: 解压/压缩 49 decompress/compress 50 :param tar_name: 压缩包绝对路径 后缀为tar/zip/rar 51 :param compressed_files: 压缩文件绝对路径 如果是解压:请输入目录 52 :param winrar_exe: winexe执行文件路径 53 :return: 54 """ 55 if opr == 'compress': 56 LOG_DEBUG('开始winrar压缩文件') 57 timer = time.time() 58 ret = exec_command_with_popen('{} a -r -ep1 -df {} {}'.format(winrar_exe, tar_name, compressed_files)) 59 usetime = round(time.time() - timer, 4) 60 LOG_DEBUG("winrar压缩文件返回值:{}".format(ret)) 61 if ret: 62 LOG_ERROR('winrar压缩文件失败') 63 usetime = 0 64 return usetime 65 elif opr == 'decompress': 66 LOG_DEBUG('开始winrar解压文件') 67 timer = time.time() 68 ret = exec_command_with_popen('{} x {} {}'.format(winrar_exe, tar_name, compressed_files)) 69 usetime = round(time.time() - timer, 4) 70 LOG_DEBUG("winrar解压文件返回值:{}".format(ret)) 71 if ret: 72 LOG_ERROR('winrar解压文件失败') 73 usetime = 0 74 return usetime 75 else: 76 raise Exception("请输入opr参数['decompress', 'compress']") 77 78 79 def rar7z(opr, tar_name, compressed_files, winrar_exe=r'"C:Program Files7-Zip7z.exe"'): 80 """ 81 7z解压缩 82 :param opr: 解压/压缩 83 decompress/compress 84 :param tar_name: 压缩包绝对路径 后缀为7z 85 :param compressed_files: 压缩文件绝对路径 如果是解压:请输入目录 86 :param winrar_exe: winexe执行文件路径 87 :return: 88 """ 89 if opr == 'compress': 90 LOG_DEBUG('开始rar7z压缩文件') 91 timer = time.time() 92 ret = exec_command_with_popen('{} a -t7z {} {} -r'.format(winrar_exe, tar_name, compressed_files)) 93 usetime = round(time.time() - timer, 4) 94 LOG_DEBUG("rar7z压缩文件返回值:{}".format(ret)) 95 if 'Ok' not in ret: 96 LOG_ERROR('rar7z压缩文件失败') 97 usetime = 0 98 return usetime 99 elif opr == 'decompress': 100 LOG_DEBUG('开始rar7z压缩文件') 101 timer = time.time() 102 ret = exec_command_with_popen('{} x {} -o{} -aoa'.format(winrar_exe, tar_name, compressed_files)) 103 usetime = round(time.time() - timer, 4) 104 LOG_DEBUG("rar7z解压文件返回值:{}".format(ret)) 105 if 'Ok' not in ret: 106 LOG_ERROR('rar7z解压文件失败') 107 usetime = 0 108 return usetime 109 else: 110 raise Exception("请输入opr参数['decompress', 'compress']") 111 112 113 def bandizip(opr, tar_name, compressed_files, winrar_exe=r'"C:Program FilesBandizipBandizip.exe"'): 114 """ 115 bandizip解压缩 116 :param opr: 解压/压缩 117 decompress/compress 118 :param tar_name: 压缩包绝对路径 后缀为zip 119 :param compressed_files: 压缩文件绝对路径 如果是解压:请输入目录 压缩可输入目录或文件 120 :param winrar_exe: winexe执行文件路径 121 :return: 122 """ 123 if opr == 'compress': 124 LOG_DEBUG('开始bandizip压缩文件') 125 timer = time.time() 126 ret = exec_command_with_popen('{} a -y {} {}'.format(winrar_exe, tar_name, compressed_files)) 127 usetime = round(time.time() - timer, 4) 128 LOG_DEBUG("bandizip压缩文件返回值:{}".format(ret)) 129 if ret: 130 LOG_ERROR('bandizip压缩文件失败') 131 usetime = 0 132 return usetime 133 elif opr == 'decompress': 134 LOG_DEBUG('开始bandizip解压文件') 135 timer = time.time() 136 ret = exec_command_with_popen('{} x -y -o:{} {} '.format(winrar_exe, compressed_files, tar_name)) 137 usetime = round(time.time() - timer, 4) 138 LOG_DEBUG("bandizip解压文件返回值:{}".format(ret)) 139 if ret: 140 LOG_ERROR('bandizip解压文件失败') 141 usetime = 0 142 return usetime 143 else: 144 raise Exception("请输入opr参数['decompress', 'compress']") 145 146 147 def read_process_name_config(): 148 with codecs.open(filename='process_name_config.txt', mode='r', encoding='utf-8', errors='ignore') as f: 149 content = str(f.read().lower()) 150 process_name_list = content.strip().replace(' ', ' ').split(' ') 151 process_name_list = [item for item in process_name_list if item] 152 return process_name_list 153 154 155 def read_config(): 156 config_content = '' 157 try: 158 with codecs.open('config.json', 'r', 'utf-8', 'ignore') as f: 159 config_content = f.read() 160 config_content = json.loads(config_content) 161 except Exception: 162 config_content = {} 163 return config_content 164 165 166 def get_host_ip(): 167 """ 168 查询本机ip地址 169 :return: 170 """ 171 try: 172 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 173 s.connect(('8.8.8.8', 80)) 174 ip = s.getsockname()[0] 175 except Exception as e: 176 print e 177 f = os.popen('ipconfig', "rb") 178 cmd_ret = f.read() 179 cmd_ret = cmd_ret.decode('gbk', 'ignore') 180 ip_list = re.findall(r'(d+.d+.d+.d+)', cmd_ret) 181 ip = ip_list[0] 182 finally: 183 try: 184 s.close() 185 except Exception: 186 pass 187 return ip 188 189 190 def exec_command_with_popen(cmd): 191 """ 192 执行windows或者linux命令行 193 :param cmd: 命令 194 :return: 返回值 195 """ 196 LOG_DEBUG('执行cmd命令:{}'.format(cmd)) 197 f = os.popen(cmd, "r") 198 ret = f.read() # 读文件 199 ret = ret.decode('gbk', errors='ignore') 200 f.close() 201 return ret 202 203 204 def get_all_windows_pid(): 205 """获取Windows进程PID""" 206 content = exec_command_with_popen('tasklist').strip().lower().split(' ') 207 process_map = {} 208 for item in content[2:]: 209 item_split_list = item.split(' ') 210 item_split_list = [i for i in item_split_list if i] 211 key_name = item_split_list[0] 212 key_value = item_split_list[1].strip().split(' ')[0] 213 process_map[key_name] = key_value 214 return process_map 215 216 217 def get_process_pid(process_name): 218 """ 219 获取Linux/Windows系统进程的PID 220 :param process_name: 221 :return: 222 """ 223 #{"进程名": 进程PID} 224 process_map = {} 225 for proc in psutil.process_iter(): 226 process_map[proc.name()] = proc.pid 227 pid = process_map[process_name] 228 LOG_DEBUG("process_name:[{}], pricess_pid:[{}]".format(process_name, pid)) 229 return pid 230 231 232 def get_pid_handle(process_map, process_name): 233 """ 234 获取进程句柄数 235 :param process_map: 236 :param process_name: 237 :return: 238 """ 239 wmi_conn = wmi.WMI() 240 process_name = process_name.lower() 241 pid = int(process_map[process_name]) 242 handle_num = '' 243 private_mem = '' 244 try: 245 handle_num = wmi_conn.Win32_Process(name=process_name)[0].HandleCount 246 except Exception: 247 handle_num = ' ' 248 try: 249 private_mem = int(wmi_conn.Win32_Process(name=process_name)[0].PrivatePageCount) / 1024 250 except Exception: 251 private_mem = ' ' 252 finally: 253 return (str(process_name), str(handle_num), str(private_mem)) 254 255 256 def get_process_memory_percent(process_name): 257 """ 258 获取进程内存占用 259 :param process_name: 260 :return: 261 """ 262 try: 263 process_pid = get_process_pid(process_name) 264 p = psutil.Process(process_pid) 265 memory_percent = round(p.memory_info().rss / 1024 / 1024, 4) 266 LOG_DEBUG('process_name:[{}], process_memory:[{}MB]'.format(process_name, memory_percent)) 267 return memory_percent 268 except Exception as e: 269 LOG_ERROR("获取进程内存利用率异常{}".format(e)) 270 # 存在获取为空的现象,增加一次降低概率 271 try: 272 process_pid = get_process_pid(process_name) 273 p = psutil.Process(process_pid) 274 memory_percent = round(p.memory_info().rss / 1024 / 1024, 4) 275 LOG_DEBUG('process_name:[{}], process_memory:[{}MB]'.format(process_name, memory_percent)) 276 return memory_percent 277 except Exception as e: 278 LOG_ERROR("获取进程内存利用率异常{}".format(e)) 279 def get_process_io(process_name): 280 """ 281 获取进程IO 282 :param process_name: 283 :return: 284 """ 285 try: 286 process_pid = get_process_pid(process_name) 287 p = psutil.Process(process_pid) 288 io_read = round(p.io_counters().read_count / 1024 / 1024, 4) 289 io_write = round(p.io_counters().write_count / 1024 / 1024, 4) 290 LOG_DEBUG('process_name:[{}], io_read:[{}Mbps/s], io_write:[{}Mbps/s]'.format(process_name, io_read, io_write)) 291 return (io_read,io_write) 292 except Exception as e: 293 LOG_ERROR("获取进程IO异常{}".format(e)) 294 # 存在获取为空的现象,增加一次降低概率 295 try: 296 process_pid = get_process_pid(process_name) 297 p = psutil.Process(process_pid) 298 io_read = round(p.io_counters().read_count / 1024 / 1024, 4) 299 io_write = round(p.io_counters().write_count / 1024 / 1024, 4) 300 LOG_DEBUG( 301 'process_name:[{}], io_read:[{}Mbps/s], io_write:[{}Mbps/s]'.format(process_name, io_read, io_write)) 302 return (io_read, io_write) 303 except Exception as e: 304 LOG_ERROR("获取进程IO异常{}".format(e)) 305 306 307 def get_process_cpu(process_name): 308 """ 309 获取进程CPU占用率 310 :param process_name: 311 :return: 312 """ 313 try: 314 #物理cpu个数 315 cpu_count = psutil.cpu_count(logical=False) 316 process_pid = get_process_pid(process_name) 317 p = psutil.Process(process_pid) 318 cpu_percent = round(p.cpu_percent(interval=1) / cpu_count, 4) 319 LOG_DEBUG('process_name:[{}], cpu_percent:[{}%]'.format(process_name, cpu_percent)) 320 return cpu_percent 321 except Exception as e: 322 LOG_ERROR("获取进程CPU占用率异常{}".format(e)) 323 #存在获取为空的现象,增加一次降低概率 324 try: 325 # 物理cpu个数 326 cpu_count = psutil.cpu_count(logical=False) 327 process_pid = get_process_pid(process_name) 328 p = psutil.Process(process_pid) 329 cpu_percent = round(p.cpu_percent(interval=1) / cpu_count, 4) 330 LOG_DEBUG('process_name:[{}], cpu_percent:[{}%]'.format(process_name, cpu_percent)) 331 return cpu_percent 332 except Exception as e: 333 LOG_ERROR("获取进程CPU占用率异常{}".format(e)) 334 335 336 def get_fs_info(): 337 """ 338 获取文件系统信息。 339 包含分区的大小、已用量、可用量、使用率、挂载点信息。 340 """ 341 tmplist = [] 342 c = wmi.WMI() 343 for physical_disk in c.Win32_DiskDrive(): 344 for partition in physical_disk.associators("Win32_DiskDriveToDiskPartition"): 345 for logical_disk in partition.associators("Win32_LogicalDiskToPartition"): 346 tmpdict = {} 347 tmpdict["Caption"] = logical_disk.Caption 348 tmpdict["DiskTotal"] = long(logical_disk.Size) / 1024 / 1024 349 tmpdict["UseSpace"] = (long(logical_disk.Size) - long(logical_disk.FreeSpace)) / 1024 / 1024 350 tmpdict["FreeSpace"] = long(logical_disk.FreeSpace) / 1024 / 1024 351 # tmpdict["Percent"] = int( 352 # 100.0 * (long(logical_disk.Size) - long(logical_disk.FreeSpace)) / long(logical_disk.Size)) 353 tmplist.append(tmpdict) 354 return tmplist[0] 355 356 357 def get_dir_space(dirpath): 358 359 size = 0 360 if os.path.exists(dirpath): 361 if os.path.isdir(dirpath): 362 for root, dirs, files in os.walk(dirpath): 363 for name in files: 364 try: 365 size += os.path.getsize(os.path.join(root, name)) 366 except: 367 continue 368 #size += sum([getsize(join(root, name)) for name in files]) 369 elif os.path.isfile(dirpath): 370 size = os.path.getsize(dirpath) 371 else: 372 pass 373 size = round(size / 1024 / 1024, 4) 374 LOG_DEBUG("Dir path:[{}], size:[{}M]".format(dirpath, size)) 375 return size 376 def loadrunner(process_name, PROCESS_CPU, PROCESS_MEM, PROCESS_IO_Read, PROCESS_IO_Write, row_num, cur_time): 377 """ 378 获取性能监控数据 379 :param process_name: 380 :return: 381 """ 382 #cur_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) 383 cpu_percent = get_process_cpu(process_name) 384 mem_used = get_process_memory_percent(process_name) 385 io_read, io_write = get_process_io(process_name) 386 if process_name == LOADRUNNER_PROCESS[0]: 387 PROCESS_CPU.write(row_num, 0, label=cur_time) 388 PROCESS_MEM.write(row_num, 0, label=cur_time) 389 PROCESS_IO_Read.write(row_num, 0, label=cur_time) 390 PROCESS_IO_Write.write(row_num, 0, label=cur_time) 391 PROCESS_CPU.write(row_num, 1, label=cpu_percent) 392 PROCESS_MEM.write(row_num, 1, label=mem_used) 393 PROCESS_IO_Read.write(row_num, 1, label=io_read) 394 PROCESS_IO_Write.write(row_num, 1, label=io_write) 395 else: 396 for col in range(1, len(LOADRUNNER_PROCESS)): 397 if process_name == LOADRUNNER_PROCESS[col]: 398 PROCESS_CPU.write(row_num, col+1, label=cpu_percent) 399 PROCESS_MEM.write(row_num, col+1, label=mem_used) 400 PROCESS_IO_Read.write(row_num, col+1, label=io_read) 401 PROCESS_IO_Write.write(row_num, col+1, label=io_write) 402 403 404 def write_data_in_xls(): 405 """ 406 写数据到xls 407 :return: 408 """ 409 write_xls_cursor = xlwt.Workbook(encoding='utf-8') 410 return write_xls_cursor 411 #worksheet.write(row, col, label=data) 412 #write_xls_cursor.save(file_name) 413 414 415 def read_data_from_xls(file_path): 416 """ 417 读取xls数据 418 :return: 419 """ 420 try: 421 read_xls_cursor = xlrd.open_workbook(file_path, formatting_info=True) 422 return read_xls_cursor 423 except Exception: 424 raise Exception, "读取xls报错" 425 426 def vital_xls_col_data(workbook, cols_name): 427 """ 428 统计xls每列数据 429 :return: 430 """ 431 process_nrows = workbook.nrows 432 process_data_dict = {} 433 col = 1 434 try: 435 for p_name in cols_name: 436 single_process_data = [] 437 for row in range(1, process_nrows): 438 table_value = workbook.cell(row, col).value 439 if table_value == "": 440 table_value = 0.0 441 single_process_data.append(table_value) 442 col += 1 443 process_data_dict[p_name] = single_process_data 444 except Exception as e: 445 LOG_ERROR(e) 446 return process_data_dict 447 448 449 def vital_xls_row_data(workbook): 450 """ 451 统计每行数据 452 :param workbook: 453 :return: 454 """ 455 process_nrows = workbook.nrows 456 process_ncols = workbook.ncols 457 458 process_rows_sum = [] 459 for row in range(1, process_nrows): 460 process_row_data = [] 461 process_row_sum = 0 462 for col in range(1, process_ncols): 463 table_value = workbook.cell(row, col).value 464 if table_value == "": 465 table_value = 0.0 466 process_row_data.append(table_value) 467 process_row_sum = calc_average_value(process_row_data)[0] 468 process_rows_sum.append(process_row_sum) 469 return process_rows_sum