代码记录
#utf8 #python3.4 import os def GetDesktopPath(): #获取用户下载地址并且格式化地址 注意~的使用 非常方便获取user目录 downloaddir = os.path.join(os.path.expanduser("~"), 'Downloads') format_dir = downloaddir.replace('\\','/') return format_dir class decoder: #解压缩tar压缩包 def extract_tar(self,path,snap_name): import tarfile tarobj = tarfile.open(path+'/'+snap_name+'.tgz','r') while not os.path.exists(path+'/'+snap_name): tardoc = tarobj.getnames() for file in tardoc: tarobj.extract(file,path+'/'+snap_name) tarobj.close() #进入已经解压缩的包 并找到想要的文件 def find_file(self,snap_name): from os import listdir import re file_list = listdir(path+'/'+snap_name+'/dumps') #print(file_list) 测试位 print('#####decode tool#####') print('pls select what you want:') print('1.hw info') print('2.clsuter info') while True: select = input('your choice:') if select == '1': for file in file_list: match = re.match('svcout.internalstorage*',file) if match != None: svcinfo = file break if select == '2': for file in file_list: match = re.match('nodeinfo*',file) if match != None: svcinfo = file break else: print('pls reselect your choice') continue svc_path = path + '/'+snap_name+'/dumps'+'/'+svcinfo return [select,svc_path] def open_file(self,select,logfile_path): #利用数据格式 得到想要的命令输出 file_open = open(logfile_path,'r') content = [] if select == '1': print(''' ********************************************* 1.Disk info 2.I want to input command by myself ********************************************* ''') svc_command = input('pls input your request#:') if svc_command == '1': svc_command = 'lsdrive' # 打印整个命令的输出 while True: line = file_open.readline() if svc_command in line: # print(line) content.append(line) while True: line = file_open.readline() if 'svcinfo' in line: break if not len(line): # print(line) content.append(line) continue else: # print(line) content.append(line) continue if 'lsarraymemberprogress' in line: break else: continue #print(content) else: print('Pls select your choice', end='') print(''' ********************************************* '1':'lsenclosurepsu' '2':'lsenclosurecanister' '3':'lsenclosurebattery' '4':'lsenclosure' '5':'svcinfo lsdrive -delim : ' '6':'svcinfo lsenclosure -delim : ' ********************************************* ''') diy_select = input('Your choice:') diy_command = decoder.user_defined_command(self) out_put= decoder.command_output(self,logfile_path,diy_command['%s'%diy_select]) print('The output:', end='') for out_put_line in out_put: print(out_put_line) if select == '2': canister_info = file_open.read() print(canister_info) file_open.close() return content def find_failed_disk(self,content_disk_fail): #最重要的一个方法 找到出问题的部分 diskfail = [] for failinfo in content_disk_fail: if 'degraded' in failinfo: # print(failinfo) diskfail.append(failinfo) if 'offline' in failinfo: # print(failinfo) diskfail.append(failinfo) if '/n' in failinfo: break else: continue if diskfail: # 查看机器的坏盘enclosure id print(diskfail) data_clear = [] all_disk_failed_info = [] for disk_enclosure in diskfail: print('###################################' '# below is the failed disk info: #' '################################### ') data_clear = str(disk_enclosure).split(':') print(disk_enclosure) print('failed drive_id is :%s'%data_clear[0]) print('related enclosure id is:%s'%data_clear[9]) ibase_refer_clear = [] ibase_refer_disk = 0 for ibase_refer in content_disk_fail: ibase_refer_clear = str(ibase_refer).split(':') if len(ibase_refer_clear) >=10: if ibase_refer_clear[9] == data_clear[9]: #通过比对enclosure id 累加确定柜子硬盘数量 ibase_refer_disk = ibase_refer_disk + 1 else: continue else: continue print('This enclosure has %s disks'%ibase_refer_disk) all_disk_failed_info = data_clear + all_disk_failed_info return all_disk_failed_info else: return 0 def user_defined_command(self): svc_command = {'1':'lsenclosurepsu','2':'lsenclosurecanister','3':'lsenclosurebattery','4':'lsenclosure' ,'5':'svcinfo lsdrive -delim : ','6':'svcinfo lsenclosure -delim : ' } return svc_command def command_output(self,logfile_path,svc_command): #获取命令输出 file_open = open(logfile_path, 'r') content_command_output = [] # 打印整个命令的输出 while True: line = file_open.readline() if svc_command in line: # print(line) content_command_output.append(line) while True: line = file_open.readline() if 'svcinfo' in line: break if not len(line): # print(line) content_command_output.append(line) continue else: # print(line) content_command_output.append(line) continue if 'lsarraymemberprogress' in line: break else: continue return content_command_output ##########主函数########### while True: print(''' ************************************************* * svcdecoder-tool * ************************************************* ''') snap_name = input('pls input your snap name:') path = GetDesktopPath() obj = decoder() #成为decoder类的一个对象 obj.extract_tar(path,snap_name) #解压snap得到路径 svc_select = obj.find_file(snap_name) #从find_path中获取svclog的path content_main = obj.open_file(svc_select[0],svc_select[1])#打开并获取常用的命令输出 analysis_file_path = svc_select[1] #需要解析的日志路径 disk_info=obj.find_failed_disk(content_main)#找到坏盘的id和enclosure id #disk_info[0] disk id disk_info[9] enslodure id command = obj.user_defined_command() #print(command['5']+disk_info[0]) #判断坏盘是否存在# if disk_info: i = int(len(disk_info)/14) print('len(disk_info)=%s'%len(disk_info)) for x in range(0,i): failed_disk_info = obj.command_output(analysis_file_path,command['5']+disk_info[0+14*x]) print('#######################以下是坏盘具体信息 注意比对drive id###############################') print('Drive id:%s'%disk_info[0+14*x]) enclosure_info = obj.command_output(analysis_file_path, command['6'] + disk_info[9+14*x]) print('Related_enclosure_',end='')#enclosure mt print(enclosure_info[10]) print('Related_enclosure_', end='')#enclosure sn print(enclosure_info[11]) print('Failed_disk_',end='')#disk fru print(failed_disk_info[11]) print('Failed_disk_',end='')#disk id print(failed_disk_info[12]) else: print('no disk failed or maybe you need run disk analysis option.') ###功能:可以解析坏盘和相关信息 简化工作重复性 同时可以输入自定义命令得到想看的数据清洗结果###