UI界面实现SSH登录服务器并执行命令监控
一、通过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登录服务器并执行命令监控的更多相关文章
- Python通过ssh连接服务器并执行命令
[本文出自天外归云的博客园] 脚本示例如下: # coding:utf-8 import time,paramiko,re,StringIO def exec_shell(command): ''' ...
- expect远程登录服务器并执行命令
#!/usr/bin/expectset timeout 120 #设置执行超时时间,任何输入120秒后退出set password "password" ...
- ssh远程连接linux服务器并执行命令
详细方法: SSHClient中的方法 参数和参数说明 connect(实现ssh连接和校验) hostname:目标主机地址 port:主机端口 username:校验的用户名 password:登 ...
- java ssh远程服务器并执行多条shell命令
java ssh远程服务器并执行多条命令 import java.io.BufferedReader; import java.io.IOException; import java.io.Input ...
- ssh登录服务器提示错误no hostkey alg
ssh登录服务器提示错误no hostkey alg ssh root@192.168.1.100 -vvv 提示失败: no hostkey alg 登录到192.168.1.100服务器 rm - ...
- centos linux ip地址无法连接数据库,ssh登录服务器时必须使用22端口
问题一:连接数据库时直接使用ip地址无法连接,必须使用ssh方式才能连接? 问题二:ssh登录服务器时必须使用22端口,在/etc/ssh/sshd_config中添加了10086端口,防火墙中已开启 ...
- Mac 无密码 SSH 登录服务器
Mac 无密码 SSH 登录服务器,只需要简单三步,不再需要记住账号密码,快速进入服务器 第一步,生成密钥对 在当前用户下创建.ssh目录 mkdir ~/.ssh 使用命令ssh-keygen生成密 ...
- 【Shell实战】批量在多台服务器上执行命令
功能说明:批量在多台服务器上执行命令 #!/bin/bash # ========================================== # 功能:批量在多台服务器上执行命令 # 方法: ...
- Python 实现远程服务器批量执行命令
paramiko 远程控制介绍 Python paramiko是一个相当好用的远程登录模块,采用ssh协议,可以实现linux服务器的ssh远程登录.首先来看一个简单的例子 import parami ...
- python paramiko实现ssh上传下载执行命令
paramiko ssh上传下载执行命令 序言 最近项目经常需要动态在跳板机上登录服务器进行部署环境,且服务器比较多,每次完成所有服务器到环境部署执行耗费大量时间.为了解决这个问题,根据所学的执行实现 ...
随机推荐
- CImage类使用
前言 CImage类是基于GDI+的,但是这里为什么要讲归于GDI? 主要是基于这样的考虑: 在GDI+环境中,我们可以直接使用GDI+ ,没多少必要再使用CImage类 但是,如果 ...
- SecPoint Port Scanner v4.0
SecPoint Port Scanner v4.0 Usage: portscanner <IP> or <hostname> [options] 选项: -p <st ...
- Taro3 扫描不同二维码参数不同,但是热启动之后参数不变 根据环境不同更换域名
热启动:先执行缓存的静态数据,然后再执行页面代码.比如右上角退出或者按home键错误用法:用的Taro3 react function函数,之前用的 Taro.getLaunchOptionsSyn ...
- Spring boot jar包解压后重新压缩命令
进入解压的目录/demo,运行 jar cvfM0 demo.jar * 压缩后的项目即可运行 参考:https://www.cnblogs.com/liyanbin/p/6088458.html
- [Unity3D 小Tricks] 如何修改Unity3d脚本默认模板?
众所周知,unity默认的模板总是Update()和Start(),但往往我们并不需要,每次都要手动删除非常麻烦. 但可以更改如下模板文件 C:\Program Files\Unity 2020.3. ...
- UNIT ONE
一.机器语言 1.机器指令 0与1构成 2.机器可以直接执行 二.汇编语言 1.汇编指令 要翻译成机器指令,机器才可以运行 2.给人看的,主要是人看得懂 VS 机器.汇编. ...
- 48. Rotate Image via java
need to use scratch to find the pattern class Solution { public void rotate(int[][] matrix) { int n= ...
- vue后台管理系统——用户管理模块
电商后台管理系统的功能--用户管理模块 1. 用户管理概述 通过后台管理用户的账号信息,具体包括用户信息的展示.添加.修改.删除.角色分配.账号启用/注销等功能. 用户信息列表展示 添加用户 修改用户 ...
- 项目实训 DAY17-18
第一天,与后端的同学交接,先跟他说了怎么安装依赖库,弄完后他那边运行有些问题. 第二天,后端的同学说可以运行但无法部署,我思考后一起商量着只做静态模型(本身不同的两张图片只有input有区别),然后添 ...
- 三大常用集群leader选举+哨兵模式原理
一,Zookeeper集群的leader选举 Zookeeper的选举机制两个触发条件:集群启动阶段和集群运行阶段leader挂机(这2种场景下选举的流程基本一致) 1,Zookeeper集群中的fo ...