python监控mysql主从

监控mysql主从的python脚本,不是自己写的,非原创,可以学习借鉴。

#!/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: 
            return 0,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())) 
        if not self.IO and not self.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) 
            return 0 
        if self.IO == "Yes": 
            if self.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) 
                return 0 
            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) 
                return 1 
        else: 
            if self.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) 
                return 2 
            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) 
                return 3 
 
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 
        while True: 
            threads = [] 
            if self.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:wangwei03@gyyx.cn\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() 
        return True 
    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()
QQ截图20161101174400.png

配置文件的名字为: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丛库服务器状态监控

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 你 !你 !你 ! 说得就是你 !-----谁啊? 你啊!还有谁啊!就是你!----咋了?!! 你每天睡得那么晚还...
    遇见晚晴阅读 299评论 2 6
  • 我们曾经一见如故 我们曾经推心置腹 我们幻想笑傲江湖 我们感叹情为何物 我们现在天各一方 我们现在各怀梦想 我们联...
    清风徐阅读 108评论 0 0
  • 写作打卡第12天,感谢沐叁小伙伴的陪伴。 前几天是在有道云笔记写东西,自己写沐叁看。虽然有沐叁提点和监督,但总还是...
    小米屋阅读 539评论 0 50