mirror of
https://github.com/ranl/monitor-utils.git
synced 2024-11-14 03:53:42 +01:00
224 lines
5.3 KiB
Python
Executable File
224 lines
5.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
'''
|
|
Monitor Apache Solr via HTTP for Zabbix
|
|
'''
|
|
|
|
from optparse import OptionParser
|
|
import xml.etree.ElementTree as ET
|
|
import urllib2
|
|
|
|
|
|
def prepareOpts():
|
|
'''
|
|
Parse option from the shell
|
|
'''
|
|
|
|
cmds = [
|
|
'ping',
|
|
'dataimportDocumentsProcessed',
|
|
'indexBehindMaster'
|
|
]
|
|
|
|
def err( string ):
|
|
print 'Error: {0}'.format( string )
|
|
parser.print_help()
|
|
print __doc__
|
|
exit(1)
|
|
|
|
parser = OptionParser()
|
|
parser.add_option('-u', '--url', dest='url', type='string', help='solr url', default=None)
|
|
parser.add_option('-U', '--user', dest='user', type='string', help='username', default=None)
|
|
parser.add_option('-P', '--passwd', dest='passwd', type='string', help='password', default=None)
|
|
parser.add_option('-t', '--timeout', dest='timeout', type='float', help='how many seconds to wait for each http request', default=5)
|
|
parser.add_option('-c', '--cmd', dest='cmd', type='choice', choices=cmds, help='what to check: {0}'.format(cmds) )
|
|
parser.add_option('-C', '--core', dest='core', type='string', help='core id', default=None)
|
|
parser.add_option('-H', '--handler', dest='handler', type='string', help='dataimport handler name', default=None)
|
|
(opts, args) = parser.parse_args()
|
|
|
|
if not opts.cmd:
|
|
err('missing -c')
|
|
if (opts.user and not opts.passwd) or (not opts.user and opts.passwd):
|
|
err('missing username or password')
|
|
if not opts.url:
|
|
err('missing solr http url')
|
|
if opts.cmd == 'dataimportDocumentsProcessed':
|
|
if opts.core is None:
|
|
err('missing core id !')
|
|
if opts.handler is None:
|
|
err('missing handler name !')
|
|
|
|
return opts
|
|
|
|
|
|
class SolrMonitor():
|
|
'''
|
|
Monitor Apache Solr via http
|
|
'''
|
|
|
|
def __init__(self, url, timeout=5, username=None, passwd=None):
|
|
self.url = url
|
|
self.timeout = timeout
|
|
self.username = username
|
|
self.passwd = passwd
|
|
|
|
if self.url.endswith('/'):
|
|
self.url = self.url[:-1]
|
|
|
|
self._get_auth()
|
|
|
|
def _get_auth(self):
|
|
'''
|
|
Build an Auth opener for HTTP connection
|
|
'''
|
|
if not self.username or not self.passwd:
|
|
return
|
|
basic = urllib2.HTTPBasicAuthHandler()
|
|
basic.add_password(
|
|
realm='Solr',
|
|
uri=self.url,
|
|
user=self.username,
|
|
passwd=self.passwd
|
|
)
|
|
digest = urllib2.HTTPDigestAuthHandler()
|
|
digest.add_password(
|
|
realm='Solr',
|
|
uri=self.url,
|
|
user=self.username,
|
|
passwd=self.passwd
|
|
)
|
|
|
|
urllib2.install_opener(
|
|
urllib2.build_opener(basic, digest))
|
|
|
|
def _getXmlData(self, url):
|
|
'''
|
|
create an http request to url and return the data
|
|
in case of a problem return None
|
|
'''
|
|
|
|
try:
|
|
return ET.fromstring(
|
|
urllib2.urlopen(
|
|
url,
|
|
timeout=self.timeout
|
|
).read()
|
|
)
|
|
except urllib2.URLError:
|
|
return None
|
|
|
|
def ping(self):
|
|
'''
|
|
Check if solr ping returns True
|
|
'''
|
|
|
|
ret = 0
|
|
root = self._getXmlData(self.url + '/admin/ping')
|
|
if root is None:
|
|
return 0
|
|
|
|
if root.find('str').text == 'OK':
|
|
ret = 1
|
|
|
|
return ret
|
|
|
|
def dataimportDocumentsProcessed(self, core, handler):
|
|
'''
|
|
Return the number of processed documents
|
|
from the dataimport handler
|
|
|
|
url: http://solr:port/solr/core0/dataimportName?command=status
|
|
'''
|
|
|
|
url = '{0}/{1}/{2}?command=status'.format(
|
|
self.url,
|
|
core,
|
|
handler
|
|
)
|
|
root = self._getXmlData(url)
|
|
if root is None:
|
|
return -1
|
|
|
|
for lst in root.findall('lst'):
|
|
if lst.attrib['name'] == 'statusMessages':
|
|
for str in lst.findall('str'):
|
|
if str.attrib['name'] == 'Total Documents Processed':
|
|
return int(str.text)
|
|
|
|
return -1
|
|
|
|
# Python 2.7
|
|
# return int(
|
|
# root.findall(
|
|
# "lst[@name='statusMessages']/str[@name='Total Documents Processed']"
|
|
# )[0].text
|
|
# )
|
|
|
|
def indexBehindMaster(self):
|
|
'''
|
|
Returns the difference bewteen the slave index
|
|
and the master replicable index
|
|
'''
|
|
|
|
slave = None
|
|
master = None
|
|
root = self._getXmlData(
|
|
self.url + '/replication?command=details'
|
|
)
|
|
if root is None:
|
|
return -1
|
|
|
|
for lst in root.findall('lst'):
|
|
if lst.attrib['name'] == 'details':
|
|
|
|
# Slave
|
|
for lng in lst.findall('long'):
|
|
if lng.attrib['name'] == 'indexVersion':
|
|
slave = long(lng.text)
|
|
break
|
|
|
|
# Master
|
|
for lstm in lst.findall('lst'):
|
|
if lstm.attrib['name'] == 'slave':
|
|
for lstms in lstm.findall('lst'):
|
|
if lstms.attrib['name'] == 'masterDetails':
|
|
for lstMaster in lstms.findall('lst'):
|
|
if lstMaster.attrib['name'] == 'master':
|
|
for rep in lstMaster.findall('long'):
|
|
if rep.attrib['name'] == 'replicableVersion':
|
|
master = long(rep.text)
|
|
break
|
|
|
|
if master and slave:
|
|
break
|
|
|
|
# Python 2.7
|
|
# slave = root.findall(
|
|
# "./*[@name='details']/arr[@name='commits']/lst/long[@name='indexVersion']"
|
|
# )[0].text
|
|
# master = root.findall(
|
|
# "./lst[@name='details']/lst[@name='slave']/lst[@name='masterDetails']/lst[@name='master']/long[@name='replicableVersion']"
|
|
# )[0].text
|
|
return long(master - slave)
|
|
|
|
@staticmethod
|
|
def main():
|
|
'''
|
|
Main function
|
|
'''
|
|
|
|
opts = prepareOpts()
|
|
solr = SolrMonitor( opts.url, opts.timeout, opts.user, opts.passwd )
|
|
|
|
method = getattr(solr, opts.cmd)
|
|
k = {}
|
|
if opts.core:
|
|
k.update({'core': opts.core})
|
|
if opts.handler:
|
|
k.update({'handler': opts.handler})
|
|
print method(**k)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
SolrMonitor.main()
|