NewsBlur-viq/vendor/python-munin/plugins/mysql_replication
2016-11-11 11:06:33 -08:00

153 lines
3.9 KiB
Python
Executable file

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Inspired by http://openquery.com/files/check_replication.pl.txt
import os
import re
import MySQLdb
from vendor.munin import MuninPlugin
class MuninMySQLPlugin(MuninPlugin):
category = "MySQL"
def __init__(self):
super(MuninMySQLPlugin, self).__init__()
self._db_master = None
self._db_slave = None
# Open a connection
def get_connection(self, source):
vars = self.getvars(source)
db = None
if source == 'master':
if not self._db_master:
self._db_master = MySQLdb.connect(**vars)
db = self._db_master
else:
if not self._db_slave:
self._db_slave = MySQLdb.connect(**vars)
db = self._db_slave
return db
# Get variables plugins
def getvars(self, source):
self.con_master = dict(
user="root",
host="localhost",
)
# Search environement vars
if source == 'master':
varname = ('m_user', 'm_passwd', 'm_host', 'm_port')
replacestr = 'm_'
else:
varname = ('s_user', 's_passwd', 's_host', 's_port')
replacestr = 's_'
conninfo = {}
for k in varname:
v = os.environ.get(k)
if v:
conninfo[k.replace(replacestr, '', 1)] = v
return conninfo
# get max bin log size
def getmaxbinlogsize(self):
db = self.get_connection('master')
c = db.cursor(MySQLdb.cursors.DictCursor)
c.execute("show variables like 'max_binlog_size'")
raw = c.fetchone()
return int(raw['Value'])
# Get replication values
def getvalues(self, source):
# get values
db = self.get_connection(source)
c = db.cursor(MySQLdb.cursors.DictCursor)
c.execute("show %(source)s status" % locals())
raw = c.fetchone()
return raw
def autoconf(self):
return bool(self.get_connection('master'))\
and bool(self.get_connection('slave'))
class MuninMySQLReplicationPlugin(MuninMySQLPlugin):
"""
from master => GRANT replication client on *.* TO munin@ip IDENTIFIED BY "password";
from slave => GRANT replication client on *.* TO munin@localhost IDENTIFIED BY "password";
ex: /etc/munin/plugin-conf.d/mysql_replication
[mysql_replication]
env.m_host x.x.x.x
env.m_user munin
env.m_passwd mysqlpass
env.s_host localhost
env.s_user munin
env.s_passwd mysqlpass
"""
args = "-l 0 --base 1000"
vlabel = "delta"
info = "Show delta position from master and slave mySQL database"
fields = (
('delta', dict(
label="Delta from master",
info="Delta not replicated from master",
type="GAUGE",
draw="AREA",
)),
)
@property
def title(self):
return "MySQL delta replication"
def execute(self):
m = self.getvalues('master')
s = self.getvalues('slave')
mfilepos = -1
sfilepos = -1
maxlogsize = self.getmaxbinlogsize()
# Search number binary file
r = re.search(r'\d+$', m['File'])
if r:
mfilepos = int(r.group(0))
r = re.search(r'\d+$', s['Relay_Master_Log_File'])
if r:
sfilepos = int(r.group(0))
mposition = int(m['Position'])
fposition = int(s['Exec_Master_Log_Pos'])
# Calc delta
deltafile = (mfilepos - sfilepos) * maxlogsize
deltaposition = mposition - fposition
delta = deltafile + deltaposition
# Close connection
self.get_connection('master').close()
self.get_connection('slave').close()
return dict(
delta=delta,
)
if __name__ == "__main__":
MuninMySQLReplicationPlugin().run()