前阵子,遇到需要把nagios监控的服务统计到表格的需求,想着如果每一次改动,都要去维护表格的话,难免会有疏漏或者问题,于是观察了nagios的host.cfg,services.cfg等配置文件写了一个脚本,包含对多个主机关联到同一个服务的处理等,脚本也有局限性,就是需要把每个主机,都归类到某个组,比如Linux主机归类到Linux组,实际环境,一般也是有这样做归类的,脚本运行过程中会有文件产生,但都很小,以下是相应模块安装和脚本文件,建议在测试机上面跑完再到实际环境跑。
一,安装xlsxwriter
一个excel操作模块,可以操作多个工作表的文字、数字、公式、图表等。
pip安装方法:
#pip install XlsxWriter
源码安装方法(需下载)
#tar -zxvf XlsxWriter-master.tar.gz
#cd XlsxWriter-master
#python setup.py install
二,脚本文件:
import xlsxwriter import sys reload(sys) sys.setdefaultencoding('utf8') #注意路径 os.system("cat /usr/local/nagios/etc/hosts.cfg | grep -E 'host_name|address|hostgroups' | \ sed s/[[:space:]]// | awk '{print $1,$2,$3}' | sed -e 's/[[:space:]]$//g' > /root/autocount/hostip") #####################处理一行多个host_name情况######################## os.system("cat /usr/local/nagios/etc/services.cfg | grep -E 'host_name|service_description|contacts'|sed s/[[:space:]]// | \ awk '{print $1,$2,$3,$4,$5,$6}' | sed -e 's/[[:space:]]*$//g' | sed -e 's/,[[:space:]]/,/g' > /root/autocount/serviceip2") #含有完整行的文件,及host_name都有的 os.system("cat /usr/local/nagios/etc/services.cfg | grep 'host_name' | sed s/[[:space:]]// | awk '{print $2,$3,$4,$5,$6}' | sed s/[[:space:]]//g | awk '/,/{print $0}' > /root/autocount/serviceip1") os.system("sort -u /root/autocount/serviceip1 > /root/autocount/serviceip3") #去除重复行 with open("/root/autocount/serviceip3") as f3: #a中保存有一行多个host_name的主机 a=f3.readlines() with open("/root/autocount/serviceip2") as f4: b=f4.readlines() j=0 for i in a: k = i.strip('\n').split(',') l=3 while j < len(k): print k[j] for m in b: if k[j] in m : #b中的某一行含有一行多主机中的一个主机 print k[j] if i in m : b.insert(len(b),'host_name '+k[j]+'\n') l=0 #插入到最后,然后进入下一次的for m in b,即往后面继续for了,就到下面的那个service_description,设置l是把最近的service_description同contacts加入到b的后面,而不是所有。 if 'service_description' in m and l <= 2: print m #此时的len(b)是加入了一个host_name之后的,所以会继续往后insert b.insert(len(b),m) if 'contacts' in m and l <= 2: print m b.insert(len(b),m) l+=1 j+=1 l=3 j=0 testfile = open("/root/autocount/testfile",'w') for bb in b: print >> testfile,bb, testfile.close() #此时testfile中还是含有长主机名的,即多个主机在配置文件中显示为同一行的(关联服务) jiji=0 for i in a: try: while True: ind = b.index("host_name "+i) b.pop(ind) b.pop(ind) b.pop(ind) print "###############" jiji+=1 except: continue #利用a中先前存的类似host1,host2,host3这样关联的主机,从b中剔除。 print "jiji is %s " % jiji finall = open("/root/autocount/serviceip",'w') for kk in b: print >> finall,kk, finall.close() #关闭保存文件,现在就是不存在类似多个主机名的行了。 file1="/root/autocount/hostip" file2="/root/autocount/serviceip" f = open("/root/autocount/joinout",'w') final = open("/root/autocount/final",'w') f1=file(file1,"r") j=0 totalhost=0 for i in f1.readlines(): totalhost+=1 print >> f,i, f2=file(file2,"r") m = 2 for k in f2.readlines(): if i == k : #先判断是否主机名相等,要不如果serviceip文件服务无联系人,就会出现错乱 print "testtesttest" m = 0 continue elif m < 2 and ('host_name' not in k): print >> f,k, m+=1 else: m = 2 continue f1.close() f2.close() f.close() totalhost=totalhost/3 with open("/root/autocount/joinout") as f: a=f.readlines() linen=0 con=[] totalservice=0 for i in a: if 'service_description' in i: totalservice+=1 con.append(linen) linen+=1 else: linen+=1 print con m=1 #处理一些没有contacts的情况 for j in con: if 'contacts' not in a[j+m]: a.insert(j+m,'contacts none\n') m+=1 for x in a: print >> final,x, title = [u'序列号',u'host',u'ip',u'service',u'联系人',u'所属部门'] workbook = xlsxwriter.Workbook('Nagios监控信息统计.xlsx') worksheet = workbook.add_worksheet() worksheet.set_column('A:C',30) worksheet.set_column('D:F',30) worksheet.set_column('H:I',10) #worksheet.set_row(3,30) #worksheet.set_row(6,30) #worksheet.set_row(7,30) merge_format = workbook.add_format({ 'bold': 1, 'border': 1, 'align': 'center', 'valign': 'vcenter', 'fg_color': '#CC0033'}) merge_format1 = workbook.add_format({ 'bold': 1, 'border': 1, 'align': 'center', 'valign': 'vcenter', 'fg_color': '#D7E4BC'}) bold = workbook.add_format({ 'bold': 1, 'border': 1, 'align': 'center', 'valign': 'vcenter'}) merge_format2 = workbook.add_format({ # 'bold': 1, 'border': 1, 'align': 'center', 'valign': 'vcenter'}) format_title=workbook.add_format() format_title.set_border(1) format_title.set_bg_color('#cccccc') format_title.set_align('center') worksheet.merge_range('A1:F1','Nagios监控信息',merge_format) worksheet.merge_range('H1:I1','主机总计 服务总计',merge_format1) worksheet.write('H2',totalhost,bold) worksheet.write('I2',totalservice,bold) worksheet.write_row('A2',title,format_title) ####################################### service_list=[] count = 0 slist_end = 0 initline=3 def writetoexecl(numb,host,ip,group,service_list): global initline global slist_end slist_len=str(len(service_list)) initl=str(initline) slist_end = int(initl) + int(slist_len) - 1 slist_end1=str(slist_end) #一行的就调用write方法 if initl == slist_end1: worksheet.write('A'+initl,numb,merge_format2) worksheet.write('B'+initl,host,merge_format2) worksheet.write('C'+initl,ip,merge_format2) worksheet.write('F'+initl,group,merge_format2) else: worksheet.merge_range('A'+initl+':'+'A'+slist_end1,numb,merge_format2) worksheet.merge_range('B'+initl+':'+'B'+slist_end1,host,merge_format2) worksheet.merge_range('C'+initl+':'+'C'+slist_end1,ip,merge_format2) worksheet.merge_range('F'+initl+':'+'F'+slist_end1,group,merge_format2) servicell = initl # 输出服务和联系人 for element in service_list: print '++++++++' service1=''.join(element.keys()) contacts1=''.join(element.values()) worksheet.write('D'+servicell,service1,merge_format2) worksheet.write('E'+servicell,contacts1,merge_format2) servicell = str(int(servicell) + 1) print '++++++++' #worksheet.merge_range('A50:A60',num,merge_format) #print initl #print slist_end1 initline = int(initl) + int(slist_len) for i in a: service_dict={} #定义字典存放服务和联系人 if 'host_name' in i: host=i.split()[1] print host if 'service_description' in i: key=i.split()[1] service_dict[key]='' if 'contacts' in i: service_dict[key]=i.split()[1] #print service_dict service_list.append(service_dict) #print service_list if 'address' in i: ip = i.split()[1] print ip if 'hostgroups' in i: groups = i.split()[1] print service_list print groups count += 1 writetoexecl(count,host,ip,groups,service_list) service_list=[] continue workbook.close()
统计的效果如下: