为了加快检查和了解服务器的状态,我使用了multiprocessing.dummy多线程,pampy模式匹配和一个elementUI组件。使用shell完成检查需要3分钟,使用multiprocessing.dummy模块后只需十几秒。数据是从真实服务器获取的。importrefrompampyimportmatchdisk_usage='diskname:/dev/vda1used:35Gnouse:59GUSAGE:35.35%diskname:/dev/vdb1used:278Gnouse:190GUSAGE:56.39%'re_regular=re.compile('diskname:(/\\w+/\\w+).*USAGE:(.*)%diskname:(/\\w+/\\w+).*USAGE:(.*)%')m=match(disk_usage,re_regular,lambdaa,b,c,d:b+','+d)print(m)结果如下:35.35,56.39匹配后,这两个值可以很方便的使用进度条显示在首页显示elementUI内存百分比这是elementUI官网的进度条组件。这是使用效果:下面三点详细介绍一下:1.一行代码实现在某台服务器上实现并行免密钥登录,并且可以直接连接其他服务器执行shell脚本,之前的检查是通过shell脚本执行:#登录不同ip,依次执行/home/ssw/目录下的检查脚本foripin`cat/home/ssw/iplist`;dosshuser@$ip"/bin/sh/home/ssw/weekly_check.sh";done因为是串行执行的,所以往往会等到花落完了。于是换成python执行这些shell命令:cpu、内存、磁盘检查命令都是一样的,不同的服务只需要定义一个字典,根据ip添加相关命令即可。然后pool.map()一行实现多线程。#-*-coding:utf-8-*-importparamikoimportjsonfromdatetimeimportdatetimeimporttracebackfrompprintimportpprintfrommultiprocessing.dummyimportPoolasThreadPooldefweekly_check(ip):#基础巡检指标cmds_dict={'cpu_usage':'TIME_INTERVAL=5;LAST_CPU_INFO=$(cat/proc/stat|grep-wcpu|awk\'{打印$2,$3,$4,$5,$6,$7,$8}\');LAST_SYS_IDLE=$(echo$LAST_CPU_INFO|awk\'{print$4}\');LAST_TOTAL_CPU_T=$(echo$LAST_CPU_INFO|awk\'{print$1+$2+$3+$4+$5+$6+$7}\');睡眠${TIME_INTERVAL};NEXT_CPU_INFO=$(cat/proc/stat|grep-wcpu|awk\'{打印$2,$3,$4,$5,$6,$7,$8}\');NEXT_SYS_IDLE=$(echo$NEXT_CPU_INFO|awk\'{打印$4}\');NEXT_TOTAL_CPU_T=$(echo$NEXT_CPU_INFO|awk\'{打印$1+$2+$3+$4+$5+$6+$7}\');SYSTEM_IDLE=`echo${NEXT_SYS_IDLE}${LAST_SYS_IDLE}|awk\'{print$1-$2}\'`;TOTAL_TIME=`echo${NEXT_TOTAL_CPU_T}${LAST_TOTAL_CPU_T}|awk\'{print$1-$2}\'`;CPU_USAGE=`echo${SYSTEM_IDLE}${TOTAL_TIME}|awk\'{printf"%.2f",100-$1/$2*100}\'`;echo${CPU_USAGE}','mem_usage':'MEM_USAGE=`/usr/bin/free|awk\'/Mem/{printf("RAM使用情况:%.2f%\\n"),$3/$2*100}\'|awk\'{print$3}\'`;echo${MEM_USAGE}','disk_status':'DISK_STATUS=`df-h|grep"^/dev/vd"|awk\'{printf"diskname:%-10sused:%-5snouse:%-5sUSAGE:%.2f%\\n",$1,$3,$4,$3/$2*100}\'`;echo${DISK_STATUS}','network':'ifping-c5www.baidu.com&>/dev/null;thenecho"Network:OK";elseecho"Network:NOTOK";fi','boot_log':'B=`cat/var/log/boot.log`;if["$B"=""];thenecho"Bootlog:OK";elseecho"Bootlog:NOTOK";fi',}ifip=='172.16.1.21':cmds_dict['mysql']='mysql_pid=`ps-ef|grepmysql|grep-vgrep|awk\'{print$2}\'`;if["${mysql_pid}"=""];thenecho"Mysql_service:NOTOK";elseecho"Mysql_service:OK!pidis${mysql_pid}";fi'elifip=='172.16.1.22':cmds_dict['es']='es_pid=`ps-ef|grepela静态搜索|grep-vgrep|awk\'{print$2}\'`;if["${es_pid}"=""];thenecho"Es_service:NOTOK";elseecho"Es_service:OKpidis${es_pid}";fi'elifip=='172.16.1.23':cmds_dict['redis_cluster']='NUM=`ps-ef|grepredis|grep-vgrep|awk\'{print$2}\'|wc-l`;echo"正在运行的redis-cluster节点是$NUM"'try:#createsshclientclient=paramiko.SSHClient()#key-freeloginprivate_key=paramiko.RSAKey.from_private_key_file('/home/ssw/.ssh/id_rsa')client.set_missing_host_key_policy(paramiko.AutoAddPolicy())client.connect(hostname=ip,username='ssw',port=22,pkey=private_key,timeout=30)#创建一个空字典来存储输出结果result={}fork,vincmds_dict.items():stdin,stdout,stderr=client.exec_command(v)ifnotstderr.read():result['ip']=ipresult[k]=stdout.读().decode('utf-8').strip()else:除了Exception作为e:pprint(ip+"error:"+str(e))pprint(traceback.format_exc())finally:client.close()returnresultif__name__=='__main__':ip_list=['172.16.1.21','172.16.1.22','172.16.1.23']pool=ThreadPool(8)ret=pool.map(weekly_check,ip_list)pool.close()pool.join()#结果写入excelwithopen('/home/ssw/game_server_%s.xlsx'%datetime.now().__format__('%m-%d'),'w')asf:f.write(json.dumps(ret))有的服务器有2块盘,有的只有1块盘。这是执行脚本后输出的部分数据。格式如下:[{'cpu_usage':'11.67','disk_status':'diskname:/dev/vda1used:35Gnouse:59GUSAGE:35.35%''diskname:/dev/vdb1used:243Gnouse:225GUSAGE:49.29%','es':'Es_service:OKpidis20488','ip':'172.16.1.21','mem_usage':'27.13%','network':'Network:OK'},{'cpu_usage':'3.14','disk_status':'diskname:/dev/vda1used:23Gnouse:445GUSAGE:4.67%','ip':'172.16.1.22','mem_usage':'12.86%','network':'Network:OK','rabbitmq':'Rabbitmq_service:OKpidis1392'},]2.将数据写入mysql(使用pampy)1)创建数据库createtableweekly_check(idintnotnullauto_increment,projectvarchar(30),ipvarchar(30),cpuvarchar(30),memvarchar(30),diskLONGTEXT,networkvarchar(60),vda1varchar(20),vdb1varchar(20),serviceLONGTEXT,create_timetimestampnulldefaultcurrent_timestamp,primarykey(id));2)这里写入mysqlpampy的作用主要是找出两个磁盘的利用率,作为数据插入到“vda1”和“vdb1”字段中,这样数据库就有检查数据了。importjson,pymysqlimportrefrompampyimportmatch,HEAD,TAIL,_#前面巡检的部分数据data=[{'cpu_usage':'11.67','disk_status':'diskname:/dev/vda1used:35Gnouse:59GUSAGE:35.35%''diskname:/dev/vdb1used:243Gnouse:225GUSAGE:49.29%','es':'Es_service:OKpidis20488','ip':'172.16.1.21','mem_usage':'27.13%','network':'Network:OK','service':{'boot_log':'Bootlog:OK','front_service':'Front_service:OK!pidis16608','nodejs_service':'nodejs_service:NOTOK'}},{'cpu_usage':'3.14','disk_status':'diskname:/dev/vda1used:23Gnouse:445GUSAGE:4.67%','ip':'172.16.1.22','mem_usage':'12.86%','network':'Network:OK','rabbitmq':'Rabbitmq_service:OKpidis1392','service':{'mysql':'mysql:OK'}}]defconn_mysql(sql,value):dbparam={'host':'127.0.0.1','port':3306,'user':'root','password':'1024','数据库':'警报s','charset':'utf8'}conn=pymysql.connect(**dbparam)cursor=conn.cursor()try:cursor.execute(sql,value)conn.commit()exceptExceptionase:print('存储失败',e)conn.rollback()finally:cursor.close()conn.close()forinfoindata:sql="insertintoweekly_check(project,ip,cpu,mem,disk,network,vda1,vdb1,service)values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"disk_status=info['disk_status']#Multiple"services"使用字符串连接,例如
