一、通过paramiko实现SSH远程登录服务器、执行命令并返回信息;

二、通过wxpython实现UI化;

三、代码实现如下:

1)主程序MainUI

#coding:utf8
#!/usr/bin/env python
#@author: 9527
import wx
from MainFrameUI import MainFrameUI#子类化wxpython应用程序
#定义wx.App的子类
class MainApp(wx.App):
#@author: 9527
#定义一个应用程序的初始化方法
def OnInit(self):
#启动主程序 #创建一个MainFrame的实例
win = MainFrameUI(None)
#设置窗口的尺寸800*638
win.SetSize((1100, 800))
#设置窗体放置在屏幕中心
win.CenterOnScreen()
#显示或隐藏窗口(Frame框架可见)。其中的参数可以为 True 或False。
#frame.Hide() # 等同于frame.Show(False)
win.Show(show = True)
#设计为应用程序的顶级窗口,此处即将win设计为顶级窗口
self.SetTopWindow(win) return True if __name__ == "__main__":#创建wx.App子类(MainApp)的实例,实例化
#这行创建了应用程序对象。这行之后,所有发送到stderr或stdout的文本
#都可被wxPython重定向到一个框架。参数redirect=True决定了是否重定向。
#如果值为True,则重定向到框架,如果值为False,则输出到控制台。
app = MainApp()
#应用程序进入消息循环
app.MainLoop()

2)UI框架MainFrameUI

#coding:UTF-8
#!/usr/bin/env python
#author by No9527
import wx
import PicturepackageUI
import MultipleEffectiveServerResourceMonitorUI as MESRM
from threading import Thread
import queue class MainFrameUI(wx.Frame):
#@author: 9527
def __init__(self,parent):
wx.Frame.__init__(self,parent,-1,title="服务器资源监控",pos=wx.DefaultPosition,
style=wx.SIMPLE_BORDER|wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX) self.Ssh_load = None
#定义信息列表
self.Info_List = []
self.Info_List2= [] #设置程序最小化图标
self.SetIcon(PicturepackageUI.monitor_png.GetIcon()) #绑定工具按钮与对应事件
self.action_or_stop = True #初始化循环为真 #消息定义队列
self.QueueInfo = queue.Queue(100000) #********************************************************************************* #设置panel面板1
self.panel1 = wx.Panel(self,pos=(-1,40),size=(1100,120))
self.panel1.SetBackgroundColour("#33cccc") #主机IP地址
self.IP_Addr0 = wx.StaticText(self.panel1, label="主机IP地址", pos=(10, 34))
# 单行文本输入框(加了验证器)
self.IP_Addr1 = wx.TextCtrl(self.panel1, id=wx.ID_ANY,
pos=(75, 30), size=(150, -1))
#用户名
self.UserName0 = wx.StaticText(self.panel1, label="用户名", pos=(240, 34))
self.UserName1 = wx.TextCtrl(self.panel1, id=wx.ID_ANY,
pos=(280, 30), size=(150, -1))
#密码
self.password0 = wx.StaticText(self.panel1, label="登录密码", pos=(440, 34))
# 密码输入框
self.password1 = wx.TextCtrl(self.panel1, id=wx.ID_ANY, style=wx.TE_PASSWORD,
pos=(490, 30), size=(150, -1)) #命令
self.command0 = wx.StaticText(self.panel1, label="sar命令", pos=(650, 34))
# 密码输入框
self.command1 = wx.TextCtrl(self.panel1,value="sar -n DEV 5 -u -r", id=wx.ID_ANY,
pos=(695, 30), size=(150, -1)) #确定按钮
self.ok_btn = wx.Button(self.panel1, -1, "添加", pos=(75,80),size=(70, 20))
#取消按钮
self.cancel_btn = wx.Button(self.panel1, -1, "清空", pos=(165,80),size=(70, 20)) #********************************************************************************* #设置panel面板2
self.panel2 = wx.Panel(self,pos=(-1,150),size=(1100,200))
self.panel2.SetBackgroundColour("#ff9966") CommandInfo0=["sar命令用法: sar [ 选项 ] [ <时间间隔> [ <次数> ] ]",
"主选项和报告:",
"-b I/O 和传输速率信息状况",
"-B 分页状况",
"-d 块设备状况",
"-I { <中断> | SUM | ALL | XALL } 中断信息状况",
"-m 电源管理信息状况",
"-n { <关键词> [,...] | ALL } 网络统计信息",
"关键词可以是:",
"DEV 网卡信息统计",
"EDEV 网卡的错误统计",
"NFS NFS客户端",
"NFSD NFS服务器",
"SOCK Sockets (IPV4套接字)",
"IP IP流(IPV4)",
"EIP IP流的错误统计(IPV4)",
"ICMP ICMP流(IPV4)",
"EICMP ICMP流的错误统计(IPV4)",
"TCP TCP流(IPV4)",
"ETCP TCP流的错误统计(IPV4)",
"UDP UDP流(IPV4)",
"SOCK6 Sockets(IPV6套接字)",
"IP6 IP流(IPV6)",
"EIP6 IP流的错误统计(IPV6)",
"ICMP6 ICMP流(IPV6)",
"EICMP6 ICMP流的错误统计 (IPV6)",
"UDP6 UDP流(IPV6) ",
"-q 队列长度和平均负载",
"-r 内存利用率",
"-R 内存状况",
"-S 交换空间利用率",
"-u [ ALL ]",
"CPU 利用率",
"-v Kernel table 状况",
"-w 任务创建与系统转换统计信息",
"-W 交换信息",
"-y TTY 设备状况",
"-o {<文件路径>}"] #加入换行符链接
CommandInfo1 = "\n".join(CommandInfo0)
#设置命令提示文本框
self.CommandInfoTip = wx.StaticText(self.panel2, label="sar监测命令帮助", pos=(565, 15),size = (480,50),
style = wx.ALIGN_CENTRE_HORIZONTAL)
self.CommandInfoTip.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL))
self.CommandInfo = wx.TextCtrl(self.panel2,value=CommandInfo1,pos=(565, 45),size = (490,150),
style = wx.TE_READONLY|wx.TE_MULTILINE) # 用户名与密码显示区,内容通过后续在OnButtonClick中调用SetLabel实现 self.up_monitor = wx.StaticText(self.panel2, label="当前登录信息", pos=(30, 15),size = (480,50),
style = wx.ALIGN_CENTRE_HORIZONTAL)
self.up_monitor.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.up_monitor = wx.TextCtrl(self.panel2,value="登录信息显示在这里",pos=(30, 45),size = (490,150),
style = wx.TE_READONLY|wx.TE_MULTILINE) # 控件与事件绑定在一起
self.Bind(wx.EVT_BUTTON, self.OnButtonClick, self.ok_btn)
self.Bind(wx.EVT_BUTTON, self.OnButtonClick, self.cancel_btn)
#********************************************************************************** #设置panel面板3
self.panel3 = wx.Panel(self,pos=(-1,350),size=(1100,450))
self.panel3.SetBackgroundColour("#00cc99") # 设置log信息显示面板 self.log_info0 = wx.StaticText(self.panel3, label="log信息显示区", pos=(30, 15),size = (480,50),
style = wx.ALIGN_CENTRE_HORIZONTAL)
self.log_info0.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.log_info1= wx.TextCtrl(self.panel3,value="log信息显示在这里",pos=(30, 45),size = (1020,300),
style = wx.TE_READONLY|wx.TE_MULTILINE) #启用线程间信息传递及文本框显示线程
msd = Thread(target=self.LogInfodisplay)
msd.setDaemon(1)
msd.start() #********************************************************************************** #设置状态栏及图标工具栏
statusBar = self.CreateStatusBar()#创建状态栏,放置在框架的底部
toolbar = self.CreateToolBar()#创建工具栏,被自动放置在框架的顶部 self.Action = toolbar.AddSimpleTool(wx.NewId(),PicturepackageUI.find_png.getBitmap(),
"开始监控","点击开始服务器监控")#给工具栏增加一个工具
self.Stop=toolbar.AddSimpleTool(wx.NewId(),PicturepackageUI.Lock_png.getBitmap(),
"停止监控","停止当前监控任务")#给工具栏增加一个工具 #绑定HD图标为开始按钮
self.Bind(wx.EVT_TOOL,self.ActionMonitor,self.Action)
#绑定o图标为停止按钮
self.Bind(wx.EVT_TOOL, self.ChangeLoopParameter,self.Stop) toolbar.Realize()#实现显示工具栏 #**************************************************************************************
#函数集中定义区
#************************************************************************************** #定义开始按钮事件,开始监控线程
def ActionMonitor(self,event):
#@author: 9527
self.action_or_stop = True
event.Skip()
td = Thread(target=self.ServerMonitor)
td.setDaemon(1)
td.start() #点击按钮获取输入值
def OnButtonClick(self, event):
#@author: 9527 Display_List=[] if event.GetEventObject() == self.ok_btn:
print("确定")
if self.IP_Addr1.GetValue() == '':
wx.MessageBox("主机IP为空,请输入用户名,再继续......", "提示")
elif self.UserName1.GetValue() == '':
wx.MessageBox("用户名为空,请输入用户名,再继续......", "提示")
elif self.password1.GetValue() == '':
wx.MessageBox("密码为空,请输入密码,再继续......", "提示")
elif self.command1.GetValue() == '':
wx.MessageBox("密码为空,请输入密码,再继续......", "提示") else: if self.Info_List == [] :
#写入列表
self.Info_List.append(self.IP_Addr1.GetValue())
self.Info_List.append(self.UserName1.GetValue())
self.Info_List.append(self.password1.GetValue())
self.Info_List.append(self.command1.GetValue())
self.Info_List2.append(self.Info_List)
self.Info_List = []
else:
#清空列表
self.Info_List.clear()
for A1 in self.Info_List2 :
B1 = ['','','']
B1[0] = '主机IP:' + A1[0]
B1[1] = '用户名:' + A1[1] + ' '
B1[2] = '命令:' + A1[3] + ' ' Display_List.append("\n".join(B1)) #显示到面板panel2的“当前登录信息”
self.up_monitor.SetLabel("\n".join(Display_List)) if event.GetEventObject() == self.cancel_btn:
self.Info_List=[]
self.Info_List2.clear()
print("清空")
if self.IP_Addr1.GetValue() == '':
wx.MessageBox("IP地址,请输入用户名,再继续......", "提示")
elif self.UserName1.GetValue() == '':
wx.MessageBox("用户名为空,请输入密码,再继续......", "提示")
elif self.password1.GetValue() == '':
wx.MessageBox("密码为空,请输入密码,再继续......", "提示")
else:
self.IP_Addr1.SetValue("")
self.UserName1.SetValue("")
self.password1.SetValue("")
self.up_monitor.SetLabel("") def ServerMonitor(self):
#@author: 9527 Load_list1 = self.Info_List2 #实例化Remote_management_WayKind类
self.Ssh_load = MESRM.Remote_management_WayKind() if self.action_or_stop == True: for Load_list in Load_list1: td = Thread(target=self.Use_Monitor, args=(self, Load_list))
td.setDaemon(1)
td.start() else:
self.log_info1.AppendText('连接失败请重试\n')
pass def Use_Monitor(self, parent, Load_list):
#@author: 9527 #调用MESRM.Remote_management_WayKind的Command_Way方法
#传参parent为self是启用进程的MainFrameUI本身,Load_List为登陆了认证信息
print("调用进程已启用: ", Load_list)
self.Ssh_load.Command_Way(parent,Load_list) def ChangeLoopParameter(self,event):
#@author: 9527 event.Skip()
td = Thread(target=self.LoopControl)
td.setDaemon(1)
td.start() def LoopControl(self):
#@author: 9527 if self.action_or_stop == True:
self.action_or_stop=False
else :
self.action_or_stop=True def LogInfodisplay(self):
#@author: 9527 while True : AnswerInfo = self.QueueInfo.get() #调用UI的文本控件log_info1添加文本AppendText()
self.log_info1.AppendText(AnswerInfo) #计算文本控件行数
Text_counter = self.log_info1.GetNumberOfLines() #判断行数长度,移除前1000字符串
if Text_counter > 200: self.log_info1.Remove(0,1000)

3)SSH登录执行部分MultipleEffectiveServerResourceMonitorUI

#-*- coding: utf-8 -*-
#!/usr/bin/python
#@author: 9527 '''
用法: sar [ 选项 ] [ <时间间隔> [ <次数> ] ] 主选项和报告:
-b I/O 和传输速率信息状况
-B 分页状况
-d 块设备状况
-I { <中断> | SUM | ALL | XALL } 中断信息状况
-m 电源管理信息状况
-n { <关键词> [,...] | ALL } 网络统计信息
关键词可以是:
DEV 网卡信息统计
EDEV 网卡的错误统计
NFS NFS客户端
NFSD NFS服务器
SOCK Sockets (IPV4套接字)
IP IP流(IPV4)
EIP IP流的错误统计(IPV4)
ICMP ICMP流(IPV4)
EICMP ICMP流的错误统计(IPV4)
TCP TCP流(IPV4)
ETCP TCP流的错误统计(IPV4)
UDP UDP流(IPV4)
SOCK6 Sockets(IPV6套接字)
IP6 IP流(IPV6)
EIP6 IP流的错误统计(IPV6)
ICMP6 ICMP流(IPV6)
EICMP6 ICMP流的错误统计 (IPV6)
UDP6 UDP流(IPV6)
-q 队列长度和平均负载
-r 内存利用率
-R 内存状况
-S 交换空间利用率
-u [ ALL ]
CPU 利用率
-v Kernel table 状况
-w 任务创建与系统转换统计信息
-W 交换信息
-y TTY 设备状况
-o {<文件路径>}
将命令结果以二进制格式存放在指定文件中 ''' import paramiko class Remote_management_WayKind():
#@author: 9527 def __init__(self): self def Command_Way(self, parent,Load_list):
#@author: 9527 host_addr = Load_list[0]
user_name = Load_list[1]
ssh_loadkey = Load_list[2]
execmd01 = Load_list[3] #创建SSH连接日志文件
paramiko.util.log_to_file("paramiko666.log")
# 创建SSH对象
ssh_load = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh_load.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器
ssh_load.connect(hostname=host_addr, port=22, username=user_name, password=ssh_loadkey) # 执行命令
stdin, stdout, stderr = ssh_load.exec_command (execmd01, bufsize=1) #execmd传的参数free也是命令 stderr.channel.set_combine_stderr(stdout) #打开屏幕打印log文件,如果没有便新创建,模式a+为追加模式
log_file = open(host_addr+".log", "a+") while parent.action_or_stop: #读取正常返回信息
back_normal_info = stdout.readline() if len(back_normal_info) == 0:
break back_normal_info = host_addr + str("设备信息----- \n") +back_normal_info print(back_normal_info) #向队列压入数据,队列在MainFrame中定义
parent.QueueInfo.put(back_normal_info) #写入信息
log_file.writelines(back_normal_info) if parent.action_or_stop == 0: #调用UI的文本控件log_info1添加文本AppendText()
parent.QueueInfo.put("********************"+ host_addr + "**********已暂停监控**************\n") #关闭屏幕打印log文件
log_file.close() # 关闭连接
ssh_load.close()

4)图标定义部分PicturepackageUI

#coding:utf8
from wx.lib.embeddedimage import PyEmbeddedImage monitor_png = PyEmbeddedImage("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") find_png = PyEmbeddedImage("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") Lock_png = PyEmbeddedImage("iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADSUlEQVRIS7WWP4zcRBSHf288Y693vbfH5cIhRAKIKETJNSESokU0ICQEBVAgpQEakFIhSkQNHU2a1EFCSgIVCBBCgeZoDqQgQQDlhDZEl4S77F/bY48fxS4be2xv9iD5Oj979vN789ZviJlxL5EAmFnrOMvupklKqZTCRGBMqrW2H/l/GJPeFhSLxAADImMIysenMOwFeYjsNdK6FtfPU9Tdvv+tL26op1awvs8nojAcT+6mJrt6Y2CyrLhoChHWVoKmp/JBW0DJDiV/xyYdGTVKIYQgIiKa9EKWcWpMVpsBGWO7iZmTJImicBowIViz7PQTBBJSEIB8pyVpltVmQEo5kxoRURC0Uc4Ajg/4BHQUUPzpCUoKQFjBOdgCIlHapz3AzNY72QLf9x3HsYKLE8eR1fG24K6zqCBJ0+5f29du7nhKHnzwgdWV5XLLV7KQ4Odf/zj98YXLW91YayFEu9V8+snjb7z6Qjto2Y+WsNu02WxZe7Cxeem9j86EsQYgiPjf1lo/9MgH774dFB2zPahv0yI7u70Pz5wNY70ctE6++OyJ9SOD0ejTry5+s7F56fet02cvvPPma/NrdQfBl99tXN+91fDc90+9/sT6kUnw2OFDneCTc19f/PaHzZMvPbe2f19xUYE7CH785TcAJ44ePn7s8VnQccQrzz/z+fcbw3F4pXvtvwuYeRxGAA6s7bfq0A5avuuOo7jX6+fjZeYJFsH+kpSYJxgmLBvNVnspk95uXPjAjTU3WkGLSUPqjN3K0QFgTptuDdLP/gyHYZQZI5VSys0vY3Achszsut5DS+7LjzYnjj206eV+OkqZlOcoMKBLE1t4PgADXB2ZvubVRnUStYL6qVIB1+9FraDMINLd3tCTzsP3LTn1RbfYg+DmKNQm0yYbat1pePbtGmzBbByWZ5nvqn6cCCKvNDCMyYwBqgprC2btlKbFG0Cn4W4Pxp50PFVYxUAchePqOV0SzCHNmIDKM4v92jkkgLlfw9v4ynlstUPAYo9PkQCkVJ5nD2tHpIDJR6QQ0q04TxDgKtd1C97ZUJmWyHULf1QAB9rip1vhnNxntJRYbnqerE5semQrw4wrg7SXVFQ8DwEHA7niVWQ24R9+NXciwcXtRQAAAABJRU5ErkJggg==")

UI界面实现SSH登录服务器并执行命令监控的更多相关文章

  1. Python通过ssh连接服务器并执行命令

    [本文出自天外归云的博客园] 脚本示例如下: # coding:utf-8 import time,paramiko,re,StringIO def exec_shell(command): ''' ...

  2. expect远程登录服务器并执行命令

    #!/usr/bin/expectset timeout 120            #设置执行超时时间,任何输入120秒后退出set password "password"  ...

  3. ssh远程连接linux服务器并执行命令

    详细方法: SSHClient中的方法 参数和参数说明 connect(实现ssh连接和校验) hostname:目标主机地址 port:主机端口 username:校验的用户名 password:登 ...

  4. java ssh远程服务器并执行多条shell命令

    java ssh远程服务器并执行多条命令 import java.io.BufferedReader; import java.io.IOException; import java.io.Input ...

  5. ssh登录服务器提示错误no hostkey alg

    ssh登录服务器提示错误no hostkey alg ssh root@192.168.1.100 -vvv 提示失败: no hostkey alg 登录到192.168.1.100服务器 rm - ...

  6. centos linux ip地址无法连接数据库,ssh登录服务器时必须使用22端口

    问题一:连接数据库时直接使用ip地址无法连接,必须使用ssh方式才能连接? 问题二:ssh登录服务器时必须使用22端口,在/etc/ssh/sshd_config中添加了10086端口,防火墙中已开启 ...

  7. Mac 无密码 SSH 登录服务器

    Mac 无密码 SSH 登录服务器,只需要简单三步,不再需要记住账号密码,快速进入服务器 第一步,生成密钥对 在当前用户下创建.ssh目录 mkdir ~/.ssh 使用命令ssh-keygen生成密 ...

  8. 【Shell实战】批量在多台服务器上执行命令

    功能说明:批量在多台服务器上执行命令 #!/bin/bash # ========================================== # 功能:批量在多台服务器上执行命令 # 方法: ...

  9. Python 实现远程服务器批量执行命令

    paramiko 远程控制介绍 Python paramiko是一个相当好用的远程登录模块,采用ssh协议,可以实现linux服务器的ssh远程登录.首先来看一个简单的例子 import parami ...

  10. python paramiko实现ssh上传下载执行命令

    paramiko ssh上传下载执行命令 序言 最近项目经常需要动态在跳板机上登录服务器进行部署环境,且服务器比较多,每次完成所有服务器到环境部署执行耗费大量时间.为了解决这个问题,根据所学的执行实现 ...

随机推荐

  1. 替代学习物联网-云服务-03腾讯云MQTT

    1.登录(利用微信) https://console.cloud.tencent.com/iothub 2.新建产品 3.添加设备 4.设备详细参数 域名IP固定: iotcloud-mqtt.gz. ...

  2. 【2020NOI.AC省选模拟#5】C. 光滑序列

    题目链接 原题解: 光滑的序列一定有长度为$K$的循环节. 使用动态规划,设$F(i,j)$为使前$i$个整数的和为$j$的最小修改次数. 记$cost(i,v)$为令$A_i,A_{i+K},A_{ ...

  3. 「DIARY」PKUSC2021 小结

    另外有一个纯吐槽游记版本的,还没有写完(快写完了,真的) 欢迎各路神仙来吐槽一个菜鸡的考场思路 # Day1 考场小结 总体而言,T1 完全就是送分,做得也挺快的:T2 大概是本场最难的题:然后 T3 ...

  4. Dubbo Debug大全

    com.alibaba.dubbo.rpc.RpcException: No provider available from registry 120.25.85.89:2181 for servic ...

  5. bzoj 3924

    动态点分治好题 首先我们考虑一个暴力做法: 每次修改之后选一个点作为根搜索整棵树,然后换根dp即可 考虑每次换根时,移向的点的消耗会减少子树代价之和*边权,而其余部分代价会增加剩余代价*边权 这样每次 ...

  6. 学Java的第5天,今天做了个双色球系统

    今天是学JAVA的第5天,刚刚把方法学完,然后就在这做黑马的题. 用了一个多小时时间,把他的 这些题都做完了 但是最后一道题,这个双色球系统我感觉挺有意思的 我看到这个题,分析后感觉需要4种方法: 1 ...

  7. Spring面试题大汇总

    1.Spring的IOC和AOP机制? 我们在使用spring框架其实就是为了实现IOC,依赖注入,和AOP,面向切面编程,主要有两种设计模式工厂模式和代理模式,IOC就是典型的工厂模式,通过sess ...

  8. pytorch杂谈

    inputs=tt.randn([10,3])可以随机生成高维度的数组 2. 定义一个模型为modle modle.cpu()将其调用到cpu modle.cuda()将其调用到gpu 3. 关于Cr ...

  9. Verilog 预编译

    Verilog 预编译 Verilog 语言支持宏定义(`define),参数 parameter,局域参数(localparam)以及`include等内容.这些数据常量的支持极大方便数字系统设计. ...

  10. [C++] epoll server实例

    // IO多路复用,事件驱动+非阻塞,实现一个线程完成对多个fd的监控和响应,提升CPU利用率 // epoll优点: // 1.select需要每次调用select时拷贝fd,epoll_ctl拷贝 ...