一 、paramiko 的简单介绍
Paramiko 是用 python 语言写的一个模块,远程连接到 Linux 服务器,查看上面的日志状态,批量配置远程服务器,文件上传,文件下载等,用于持续集成、服务器资源监控等都是不错的选择。
在此简单介绍一下另外几个模块,也具备相近的功能但各有利弊,其中 pexpect、winpexpect、fabric。pexpect 是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Python 模块。但是暂不支持 Windows 下的 Python 环境执行(下文是在 windows 运行脚本所以没有选择这个);winpexpect 没有深入了解,有兴趣做自己研究;fabric 模块是在 paramiko 基础上又做了一层封装,操作起来更方便。主要用于多台主机批量执行任务。
相比之下总结如下:
1、paramiko:方便嵌套系统平台中,擅长远程执行命令,文件传输。
2、fabric:方便与 shell 脚本结合,擅长批量部署,任务管理。
3、pexpect:擅长自动交互,比如 ssh、ftp、telnet。
二、paramiko 实现服务器监控的 demo 编写
monitor_server 用于编写监控对象的属性如 cpu、内存等等(部分 sshclient 实现代码也放在其中,有兴趣可以自己封装类);monitor_server:定时任务
demo 实现功能:
1、支持多台服务器多进程监控;
2、实现监控内存、网络等资源分析,目前只是打印出来结果,读者可以根据需求改成 return 形式或者记录到数据库然后分析并展示到前端;
3、实现监控的操作核心在于输入的指令,如代码中的 command = 'cat /proc/meminfo',这里需要大家对 linux 指令比较熟悉这样就可以随心所欲封装监控方法咯,加 油吧!!!!
废话不多说上代码咯……
monitor_server 文件中代码
# -*- coding: utf-8 -*-
# @Time : xxx
# @Author : xuping
# @Email : xxxx
# @File : monitor_server.py
# @Software: PyCharm
import paramiko
import re
import time
class MonitorServer:
'''
创建 ssh 连接函数
hostname, port, username, password,访问linux的ip,端口,用户名以及密码
'''
def sshConnect(self,hostname, port, username, password):
paramiko.util.log_to_file('paramiko_log')
try:
#创建一个SSH客户端client对象
sshClient = paramiko.SSHClient()
# 获取客户端host_keys,默认~/.ssh/known_hosts,非默认路径需指定
sshClient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#创建SSH连接
sshClient.connect(hostname, port, username, password)
except Exception as e:
print("SSH链接失败:[hostname:%s];[username:%s];[error:%s]" %(hostname,username,e))
exit()
return sshClient
'''
创建命令执行函数
command 传入linux运行指令
'''
def sshExecCmd(self,sshClient,command):
stdin, stdout, stderr = sshClient.exec_command(command)
filesystem_usage = stdout.readlines()
return filesystem_usage
'''
关闭ssh
'''
def sshClose(self,sshClient):
sshClient.close()
'''内存监控'''
def mem_info(self,linuxInfo):
command = 'cat /proc/meminfo'
for info in linuxInfo:#遍历所有服务器并去监控内存
hostname = info[0]
port = info[1]
username = info[2]
password = info[3]
sshClient = self.sshConnect(hostname, port, username, password)
sshRes = self.sshExecCmd(sshClient,command)
mem_values = re.findall("(\d+)\ kB", ",".join(sshRes))
MemTotal = mem_values[0]
MemFree = mem_values[1]
Buffers = mem_values[2]
Cached = mem_values[3]
SwapCached = mem_values[4]
SwapTotal = mem_values[13]
SwapFree = mem_values[14]
print('******************************内存监控,对应主机[name:%s]*********************************'% hostname)
print("*******************时间:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "******************")
print("总内存:", MemTotal)
print("空闲内存:", MemFree)
print("给文件的缓冲大小:", Buffers)
print("高速缓冲存储器使用的大小:", Cached)
print("被高速缓冲存储用的交换空间大小:", SwapCached)
print("给文件的缓冲大小:", Buffers)
if int(SwapTotal) == 0:
print(u"交换内存总共为:0")
else:
Rate_Swap = 100 - 100 * int(SwapFree) / float(SwapTotal)
print(u"交换内存利用率:", Rate_Swap)
Free_Mem = int(MemFree) + int(Buffers) + int(Cached)
Used_Mem = int(MemTotal) - Free_Mem
Rate_Mem = 100 * Used_Mem / float(MemTotal)
print(u"内存利用率:", str("%.2f" % Rate_Mem), "%")
self.sshClose(sshClient)
"""
磁盘空间监控
"""
def disk_stat(self,linuxInfo):
command = 'df -h'
for info in linuxInfo:
hostname = info[0]
port = info[1]
username = info[2]
password = info[3]
sshClient = self.sshConnect(hostname, port, username, password)
sshRes = self.sshExecCmd(sshClient, command)
sshResStr = ''.join(sshRes)
sshResList = sshResStr.strip().split('\n')
sshResLists=[]
disk_values = re.findall("(\d+)", str(sshResList[1:1]))
if disk_values == []:
fisrtStr = ' '.join(sshResList[1:3])
sshResLists.append(fisrtStr.strip().split())
for disk in sshResList[3:]:
sshResLists.append(disk.strip().split())
print('************************磁盘空间监控,对应主机[name:%s]****************************'%hostname)
print("*******************时间:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "******************")
for disklist in sshResLists:
print("\t文件系统:", disklist[0])
print("\t容量:", disklist[1])
print("\t已用:", disklist[2])
print("\t可用:", disklist[3])
print("\t已用%挂载点:", disklist[4])
print("\t磁盘挂载的目录所在(挂载点)",disklist[5])
self.sshClose(sshClient)
"""
端口监控
"""
def get_Com_Str(self,linuxInfo):
command = 'netstat -tpln'
for info in linuxInfo:
hostname = info[0]
port = info[1]
username = info[2]
password = info[3]
sshClient = self.sshConnect(hostname, port, username, password)
sshRes = self.sshExecCmd(sshClient, command)
sshResStr = ''.join(sshRes)
sshResList = sshResStr.strip().split('\n')
sshResLists = []
for sshCom in sshResList[2:]:
sshResLists.append(sshCom.strip().split())
print('******************************端口监控,对应主机[name:%s]*********************************'%hostname)
print("*******************时间:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "******************")
for temp in sshResLists:
print("\t Proto:",temp[0])
print("\t Recv-Q:", temp[1])
print("\t Send-Q:", temp[2])
print("\t Local Address:", temp[3])
print("\t Foreign Address:", temp[4])
print("\t State:", temp[5])
print("\t PID/Program name:", temp[6])
print("****************************************")
**各位小伙伴们可以再这里继续添加想要监控的资源,上面是简单的列了几个简单封装几个方法,资源监控可以根据需求不断完善即可**
monitor_task 文件中代码
# -*- coding: utf-8 -*-
# @Time : 2018/8/20 17:53
# @Author : xuping
# @Email : xxxxx
# @File : monitor_task.py
# @Software: PyCharm
import time
import threading
from monitor_server import MonitorServer
def alltask():
linuxInfo = [['linux 的ip', 端口, '用户名', '密码']]
try:
threads = []
t1 = threading.Thread(target=MonitorServer().mem_info(linuxInfo))
threads.append(t1)
#此处可以添加你想要监控的资源对应的方法,参照t1即可
for n in range(len(threads)):
threads[n].start()
except Exception as e:
print(str(e))
def roll_back(cmd, inc=30):
while True:
# 执行方法,函数
alltask()
time.sleep(inc)
roll_back("echo %time%", 1)