python寫的監控mysql主從的app

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#File:repl_wx.py
#creater:wangwei
import MySQLdb
import Queue,os,base64,time,sys,wx,threading
import ConfigParser,logging
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
class Repl:
def __init__(self,user,passwd,host,hostname):
self.user = user
self.passwd = passwd
self.host = host
self.hostname = hostname
def Slave(self,user,passwd,host,hostname):
try:
            conn = MySQLdb.connect(host,user = self.user,passwd = self.passwd,connect_timeout = 2)
            cursor = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor) 
            sql = "SHOW VARIABLES LIKE 'version'"
            cursor.execute(sql)
            alldata = cursor.fetchall()
            version = alldata[0]["Value"].split('.')[0]
            sql = "show slave status"
            cursor.execute(sql)
            alldata = cursor.fetchall()
            IO = alldata[0]["Slave_IO_Running"]
            SQL = alldata[0]["Slave_SQL_Running"]
if version == "4":
                Errno = alldata[0]["Last_errno"]
                Error = alldata[0]["Last_error"]
else:
                Errno = alldata[0]["Last_Errno"]
                Error = alldata[0]["Last_Error"]
            cursor.close()
            conn.close()
return IO,SQL,Errno,Error
except:
return0,0,0,0
class Check:
def __init__(self,app,user,passwd,host,hostname):
self.app=app
self.user = user
self.passwd = passwd
self.host = host
self.hostname = hostname
        boss = Repl(user,passwd,host,hostname)
        IO,SQL,Errno,Error = boss.Slave(self.user,self.passwd,self.host,self.hostname)
self.IO = IO
self.SQL = SQL
self.Errno = Errno
self.Error = Error
def Status(self):
        now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
ifnotself.IO andnotself.SQL:
            errlist = [self.host,self.hostname,now,'Error:Can not Connect mysql!']
            wx.CallAfter(self.app.ErrorMessage, errlist)
            a = self.hostname +  " " + self.host + " Can not Connect mysql DB!"
            logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)s %(message)s',datefmt='%Y-%m-%d %H:%M:%S',filename='slave.log',filemode='a')
            logging.error(a)
return0
ifself.IO == "Yes":
ifself.SQL == "Yes":
#print now + " " + self.hostname + " OK -slave is running " + self.host
#errlist = [self.host,self.hostname,now,'OK -slave is running!']
#wx.CallAfter(self.app.ErrorMessage, errlist)
return0
else:
#print now + " " + self.hostname + " Critical -slave SQL Error!"
                errlist = [self.host,self.hostname,now,'Critical -slave SQL Error!']
                wx.CallAfter(self.app.ErrorMessage, errlist)
                a = self.hostname +  " " + self.host + " Critical -slave SQL Error!"
                logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)s %(message)s',datefmt='%Y-%m-%d %H:%M:%S',filename='slave.log',filemode='a')
                logging.error(a)
return1
else:
ifself.SQL == "Yes":
#print now + " " + self.hostname + " Critical -slave IO Error!"
                errlist = [self.host,self.hostname,now,'Critical -slave IO Error!']
                wx.CallAfter(self.app.ErrorMessage, errlist)
                a = self.hostname +  " " + self.host + " Critical -slave IO Error!"
                logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)s %(message)s',datefmt='%Y-%m-%d %H:%M:%S',filename='slave.log',filemode='a')
                logging.error(a)
return2
else:
#print now + " " + self.hostname + " Critical -slave IO and SQL Error!"
                errlist = [self.host,self.hostname,now,'Critical -slave IO and SQL Error!']
                wx.CallAfter(self.app.ErrorMessage, errlist)
                a = self.hostname +  " " + self.host + " Critical -slave IO and SQL Error!"
                logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)s %(message)s',datefmt='%Y-%m-%d %H:%M:%S',filename='slave.log',filemode='a')
                logging.error(a)
return3
class StartScan(threading.Thread):
def __init__(self,app):
        threading.Thread.__init__(self)
self.app = app
self.timeToQuit = threading.Event()
self.timeToQuit.clear()
def stop(self):
self.timeToQuit.set()
def run(self):
self.user,self.passwd,self.hostlist,self.a,self.time = self.conf()
self.times = 1
whileTrue:
            threads = []
ifself.timeToQuit.isSet():
break
for i in range(self.a):
                host = self.hostlist[i][0]
                hostname = self.hostlist[i][1]
                boss = Check(self,self.user,self.passwd,host,hostname)
                t = threading.Thread(target=boss.Status,args=())
                threads.append(t)
#print 'Total %s Threads is working...' %self.a + '\n'
            msg = u"第" + "%s"%(self.times) + u"次掃描....."
self.app.CurrentScan(msg)
for i in range(self.a):
                threads[i].start()
                time.sleep(0.05)
for i in range(self.a):
                threads[i].join()
self.times += 1
            time.sleep(self.time)
def CurrentScan(self,msg):
        wx.CallAfter(self.app.CurrentScan, msg)
def conf(self):
        fp = ConfigParser.ConfigParser()
        fp.readfp(open('repl.ini'))
        iplist = fp.get("global", "iplist")
        user = fp.get("global", "user")
        passwd = fp.get("global", "passwd")
        time = fp.getint("global","time")
        user = base64.decodestring(user)
        passwd = base64.decodestring(passwd)
        hostlist = []
for i in iplist.split(";"):
            hostlist.append(i.split(","))
        a = len(hostlist)
return user,passwd,hostlist,a,time
def ErrorMessage(self,errlist):
        wx.CallAfter(self.app.ErrorMessage, errlist)
class ScanUnit(wx.Panel):
def __init__(self, parent,id=-1,title='',port='',):
        wx.Panel.__init__(self, parent,id)
self.parent = parent
self.id = id
self.title = title
self.scaning = wx.StaticText(self,-1,label=u"準備掃描……",style = wx.ALIGN_LEFT|wx.ST_NO_AUTORESIZE)
self.openBtn=wx.Button(self,-1,u'打開日誌')
self.openBtn.SetForegroundColour('red')
#self.openBtn.SetBackgroundColour('purple')
self.startBtn=wx.Button(self,-1,u'掃描')
self.stopBtn=wx.Button(self,-1,u'停止')
self.stopBtn.Disable()
self.list = AutoWidthListCtrl(self)
self.list.SetTextColour("red")
self.list.InsertColumn(0, 'IP', width=120)
self.list.InsertColumn(1, u'區組名稱', width=100)
self.list.InsertColumn(3, u'發生時間',width=140)
self.list.InsertColumn(4, u'返回信息',width=200)
self.list.DeleteAllItems()
self.Bind(wx.EVT_BUTTON,self.OnStart,self.startBtn)
self.Bind(wx.EVT_BUTTON,self.OnStop,self.stopBtn)
self.Bind(wx.EVT_BUTTON,self.Open,self.openBtn)
self._layout()
def _layout(self):  #佈局
        action = wx.BoxSizer(wx.HORIZONTAL)
        action.Add(self.scaning,3, wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND)#對齊沒有解決
        action.Add(self.startBtn,1, wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
        action.Add(self.stopBtn,1, wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
        action.Add(self.openBtn,1, wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
        listbox = wx.BoxSizer(wx.HORIZONTAL)
        listbox.Add(self.list, 1, wx.EXPAND)
self.box = wx.StaticBox(self, self.id, self.title,style = wx.SUNKEN_BORDER)
self.ScanUnit = wx.StaticBoxSizer(self.box, wx.VERTICAL)
self.ScanUnit.Add(action, 0, wx.ALL|wx.EXPAND, 2)
self.ScanUnit.Add(listbox, 5, wx.EXPAND, 2)
self.SetSizer(self.ScanUnit)
self.parent.sizer.Add(self,1,wx.EXPAND)
def OnStart(self,event):
self.startBtn.Disable()
self.stopBtn.Enable()
#self.DeleteItems()
self.thread=StartScan(self)
self.thread.setDaemon(True)
self.thread.start()
self.scaning.SetLabel(u'正在掃描……')
def OnStop(self,event):
self.stopBtn.Disable()
self.startBtn.Enable()
self.thread.stop()
self.scaning.SetLabel(u'停止掃描……')
def Open(self,event):
        wx.Execute("notepad slave.log")
#os.system('notepad slave.log')
def CurrentScan(self,msg): #當前掃描動作
self.scaning.SetLabel(msg)
def ErrorMessage(self,errlist):#錯誤信息
        index = self.list.InsertStringItem(sys.maxint, errlist[0])
self.list.SetStringItem(index, 1, errlist[1])
self.list.SetStringItem(index, 2, errlist[2])
self.list.SetStringItem(index, 3, errlist[3])
self.list.RefreshItem(index)
def DeleteItems(self):
self.list.DeleteAllItems()
class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES)
        ListCtrlAutoWidthMixin.__init__(self)
class MainPanel(wx.Panel):
def __init__(self,parent):
        wx.Panel.__init__(self, parent)
self.sizer = wx.GridSizer(rows=1,cols=1,hgap = 20,vgap = 15)
self.aaa = ScanUnit(self,-1,u'<Mysql主從>','8001')
self.SetSizer(self.sizer)
class CreateMenu():#創建菜單
def __init__(self,parent):
self.menuBar = wx.MenuBar()
self.file = wx.Menu()
self.close = self.file.Append(-1,u'退出(&X)')
self.menuBar.Append(self.file,u'文件(&F)')
self.help = wx.Menu()
self.about = self.help.Append(-1,u'關於(&A)')
self.menuBar.Append(self.help,u'幫助(&H)')
        parent.SetMenuBar(self.menuBar)
class MyFrame(wx.App):
    u'''''Mysql主從監控\nE-mail:[email protected]\nQQ:83521260'''
def OnInit(self):
self.frame=wx.Frame(parent=None,id=-1,title=u'Mysql主從監控程序',size=(650,450))
self.frame.SetIcon(wx.Icon('kankan.ico', wx.BITMAP_TYPE_ICO))
self.panel = MainPanel(self.frame)
self.frame.Center(direction=wx.BOTH)
self.menu = CreateMenu(self.frame)
self.frame.statusBar = self.frame.CreateStatusBar(3)
#print dir(self.frame.statusBar)
self.frame.statusBar.SetStatusWidths([-12,-12,-13]) 
self.frame.statusBar.SetForegroundColour('purple')
self.frame.statusBar.SetBackgroundColour('pink')
self.frame.StatusBar.Font.Bold = True
#self.frame.StatusBar.Font.Size = 13
self.frame.StatusBar.SetStatusText(u"好好學習",0)
self.frame.StatusBar.SetStatusText(u"天天向上",1)
self.timer=wx.PyTimer(self.Notify)
self.timer.Start(1000)
self.Notify()
self.Bind(wx.EVT_MENU,self.OnClose,self.menu.close)
self.Bind(wx.EVT_MENU,self.OnAbout,self.menu.about)
self.SetTopWindow(self.frame)
self.frame.Show()
returnTrue
def Notify(self):
        t = time.localtime(time.time())
        st = time.strftime("%Y-%m-%d %H:%M:%S",t)
self.frame.StatusBar.SetStatusText(u"當前系統時間  "+st,2)
def OnClose(self,event):
self.frame.Destroy()
def OnAbout(self,event):
        wx.MessageBox(self.__doc__,'Mysql Replication Status',wx.OK)
if __name__ == "__main__": 
    app=MyFrame(None)
    app.MainLoop()


配置文件的名字爲:repl.ini

格式爲:

[global]
user = cmVwbsdfsdfA==
passwd = SGMxNzVBcEdEZ0ZRTGsfdfV6aA==
time = 10
iplist = 192.168.8.11,煙雨江南;192.168.8.12,開天闢地;
#說明:用戶名和密碼#base64.encodestring(),base64.decodestring()加密和解密,time爲設置的超時時間(單位爲秒),iplist爲IP和名字列表

主要用於批量的mysql叢庫服務器狀態監控


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章