Last active
August 29, 2015 14:04
-
-
Save guyc/3b3819d5daf207a61796 to your computer and use it in GitHub Desktop.
Tools for writing efficient zabbix custom queries. Includes data collection for mysqladmin extended-status, mysql show slave status and port usage collected with ss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
# Command-line: | |
# Dump everything | |
# ./portstat.py | |
# | |
# Dump specific value | |
# ./portstat.py state-time-wait | |
# | |
# UserParameter=oth.port[*],/etc/zabbix/scripts/portstat.py '$1' | |
# | |
import sys | |
import pickle | |
import fcntl | |
import time | |
import os | |
import stat | |
import re | |
from collections import defaultdict | |
class Cache: | |
def __init__(self, cachefile): | |
self.cachefile = cachefile | |
def write(self, stats): | |
outfile = open(self.cachefile, 'wb') | |
pickle.dump(stats, outfile) | |
outfile.close | |
def read(self): | |
infile = open(self.cachefile, 'rb') | |
stats = pickle.load(infile) | |
infile.close() | |
return stats | |
def age(self): | |
if os.path.isfile(self.cachefile): | |
st = os.stat(self.cachefile) | |
elapsed = time.time() - st.st_mtime | |
else: | |
elapsed = None | |
return elapsed | |
#====================================================================== | |
class ReadLock: | |
def __init__(self, lockfile): | |
self.fh = open(lockfile, 'a') | |
def __enter__(self): | |
fcntl.flock(self.fh, fcntl.LOCK_SH) | |
def __exit__(self, type, value, traceback): | |
fcntl.flock(self.fh, fcntl.LOCK_UN) | |
class WriteLock(ReadLock): | |
def __enter__(self): | |
fcntl.flock(self.fh, fcntl.LOCK_EX) | |
#====================================================================== | |
class CustomQuery: | |
args = [] | |
flags = {} | |
def parseargs(self): | |
pattern = re.compile('^-([a-z])(.*)') | |
for arg in sys.argv[1:]: | |
result = re.match(pattern, arg) | |
if result: | |
self.flags[result.group(1)]=result.group(2) | |
else: | |
self.args.append(arg) | |
def generate(self): | |
stats = defaultdict(int) | |
return stats | |
def run(self): | |
self.parseargs() | |
cache = Cache(self.cachefile) | |
age = cache.age() | |
if (age is not None and age < self.max_cache_time): | |
with ReadLock(self.lockfile): | |
stats = cache.read() | |
else: | |
stats = self.generate() | |
with WriteLock(self.lockfile): | |
cache.write(stats) | |
if len(self.args): | |
for arg in self.args: | |
if arg in stats: | |
print stats[arg] | |
else: | |
print 0 | |
else: | |
for key in stats: | |
print "{0}:{1}".format(key, stats[key]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
from custom_query import CustomQuery | |
from collections import defaultdict | |
import subprocess | |
import re | |
class MysqlSlaveStat(CustomQuery): | |
def __init__(self): | |
self.cachefile = '/tmp/mysqlslave.cache' | |
self.lockfile = '/tmp/mysqlslave.lock' | |
self.max_cache_time = 80 | |
def generate(self): | |
username = self.flags['u'] | |
password = self.flags['p'] | |
cmd = ['/usr/bin/mysql','-u'+username,'-p'+password,'-e','show slave status\G'] | |
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | |
stats = defaultdict(int) | |
output = proc.communicate()[0] | |
pattern = re.compile('^\s*([^:]+): (.*)$') | |
for line in output.split('\n'): | |
result = re.match(pattern, line) | |
if result: | |
key = result.group(1) | |
value = result.group(2) | |
stats[key] = value | |
return stats | |
MysqlSlaveStat().run() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
from custom_query import CustomQuery | |
from collections import defaultdict | |
import subprocess | |
import re | |
class MysqlStat(CustomQuery): | |
def __init__(self): | |
self.cachefile = '/tmp/mysqlstat.cache' | |
self.lockfile = '/tmp/mysqlstat.lock' | |
self.max_cache_time = 80 | |
def generate(self): | |
username = self.flags['u'] | |
password = self.flags['p'] | |
cmd = ['/usr/bin/mysqladmin','-u'+username,'-p'+password,'extended-status'] | |
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | |
stats = defaultdict(int) | |
output = proc.communicate()[0] | |
pattern = re.compile('^\| ([A-Za-z_]+)\s+\| (\d+)') | |
for line in output.split('\n'): | |
result = re.match(pattern, line) | |
if result: | |
key = result.group(1) | |
value = result.group(2) | |
stats[key] = value | |
return stats | |
MysqlStat().run() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
from custom_query import CustomQuery | |
from collections import defaultdict | |
import subprocess | |
import re | |
class PortStat(CustomQuery): | |
def __init__(self): | |
self.cachefile = '/tmp/portstat.cache' | |
self.lockfile = '/tmp/portstat.lock' | |
self.max_cache_time = 80 | |
def generate(self): | |
cmd = ['/usr/sbin/ss','-a'] | |
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | |
stats = defaultdict(int) | |
# discard header | |
output = proc.communicate()[0] | |
pattern = re.compile('^([A-Z-]+)\s+\d+\s+\d+\s+\S+:(\S+)\s+\S+:(\S+)') | |
for line in output.split('\n'): | |
result = re.match(pattern, line) | |
if result: | |
state = result.group(1).lower() | |
localport = result.group(2).lower() | |
remoteport = result.group(3).lower() | |
stats['state-any'] += 1 | |
stats['state-'+state] += 1 | |
stats['local-'+localport] += 1 | |
stats['remote-'+remoteport] += 1 | |
stats['state-'+state+'-local-'+localport] += 1 | |
stats['state-'+state+'-remote-'+remoteport] += 1 | |
return stats | |
PortStat().run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment