最近由于增加了很多新的服务,服务器经常会因为oom、磁盘空间不足等原因造成各种各样的问题。所以需要写一个小工具完成对各服务器的巡检。
思路比较简单:利用paramiko这个库,在服务器上执行linux命令并将结果返回,然后通过正则表达式匹配想要的数据并进行简单数据处理 就能知道各服务器上资源占用情况了。
话不多说,上代码:
1 from functools import reduce 2 import paramiko 3 import re 4 5 worker_ips = [ 6 '192.168.1.2', 7 '192.168.1.3', 8 '192.168.1.4', 9 ] 10 11 def get_cmd_result(ip,cmd,password="***"): 12 ssh = paramiko.SSHClient() 13 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 14 ssh.connect(hostname=ip,port=22,username='root',password=password) 15 stdin,stdout,stderr = ssh.exec_command(cmd) 16 result = stdout.read() 17 18 return result 19 20 def get_re_result(rule,result): 21 result_li = re.findall(rule,result) 22 23 return result_li 24 25 def check_cpu(): 26 cpu_space_ip_dict = {} 27 for worker_ip in worker_ips: 28 result = get_cmd_result(worker_ip,'top -bi -n 4 -d 0.02') # 单独的top命令通过paramiok不会有返回值,-n 表示查看4次,-d 表示隔多久查看一次 29 space_li = get_re_result(r', (\d+.\d+) id', result) # 注意:可能由于网络原因,查看4次结果 列表长度不一定就是4,元素个数会<=4,有可能为0 30 if space_li: 31 # space = 100 - reduce(lambda a,b:float(a) + float(b), space_li) / len(space_li) 32 space = 100 - sum([float(x) for x in space_li]) / len(space_li) 33 cpu_space_ip_dict[worker_ip] = "%d%%" % space 34 else: 35 cpu_space_ip_dict[worker_ip] = "【获取服务器数据异常,需手动获取】" 36 37 return cpu_space_ip_dict 38 39 def check_df(): 40 df_space_ip_result = {} 41 for worker_ip in worker_ips: 42 result = get_cmd_result(worker_ip,'df /') 43 space = get_re_result(r'\d+%',result)[0] 44 df_space_ip_result[worker_ip] = space 45 46 return df_space_ip_result 47 48 def check_mem(): 49 mem_space_ip_dict = {} 50 for worker_ip in worker_ips: 51 result = get_cmd_result(worker_ip,'free | grep Mem') 52 mem_li = get_re_result(r'\d+',result) 53 mem_space = round(int(mem_li[1]) / int(mem_li[0]+1e-5), 2) * 100 54 mem_space_ip_dict[worker_ip] = mem_space 55 56 return mem_space_ip_dict
附上docker容器资源的解决方法:
存在可能平时的服务是跑在docker容器里面,想要获取容器中某些资源情况,可以如下操作:
1 cmd = 'docker exec test_01 df -h' 2 stdin, stdout, stderr = ssh.exec_command(cmd) 3 result = stdout.read()
更有可能需要在容器中执行多个步骤返回结果,则可以加上bash -c 参数指定多个命令,命令间用&&分隔,如下:
1 cmd = '''docker exec tets_01 bash -c "cd /home/*** && . set_path.sh && 。。。。。。"''' 2 stdin, stdout, stderr = ssh.exec_command(cmd) 3 result = stdout.read()
Comments