最近由於增加了很多新的服務,服務器經常會因為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()