mirror of
https://github.com/ranl/monitor-utils.git
synced 2026-02-05 22:55:17 +01:00
splitting IT project
This commit is contained in:
161
zabbix/scripts/activemq-monitor.py
Executable file
161
zabbix/scripts/activemq-monitor.py
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Monitor ActiveMQ server via its http web interface
|
||||
'''
|
||||
|
||||
from HTMLParser import HTMLParser
|
||||
from optparse import OptionParser
|
||||
import xml.etree.ElementTree as ET
|
||||
import json
|
||||
import urllib2
|
||||
import urllib
|
||||
|
||||
# Functions & Classes
|
||||
def prepareOpts():
|
||||
'''
|
||||
Parse option from the shell
|
||||
'''
|
||||
|
||||
cmds = ['queue_prop', 'discovery', 'subscriber_exists']
|
||||
datas = ['size', 'consumerCount', 'enqueueCount', 'dequeueCount']
|
||||
|
||||
def err( string ):
|
||||
print 'Error: {0}'.format( string )
|
||||
parser.print_help()
|
||||
print __doc__
|
||||
exit(1)
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-s', '--server', dest='server', type='string', help='ActiveMQ fqdn or ip', default='localhost')
|
||||
parser.add_option('-p', '--port', dest='port', type='int', help='ActiveMQ web interface port', default=8161)
|
||||
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('-q', '--queue', dest='queue', type='string', help='the name of the queue (implies -c queue_prop or -c subscriber_exists)')
|
||||
parser.add_option('-d', '--data', dest='data', type='choice', choices=datas, help='the name of the property to return {0} (implies -c queue_prop or -c subscriber_exists)'.format(datas) )
|
||||
parser.add_option('-C', '--client', dest='client', type='string', help='the client prefix to search (implies -c subscriber_exists and -q)' )
|
||||
(opts, args) = parser.parse_args()
|
||||
|
||||
|
||||
if not opts.cmd:
|
||||
err('missing -c')
|
||||
|
||||
if opts.cmd == 'queue_prop' and (not opts.queue or not opts.data):
|
||||
err('missing -q or -d')
|
||||
elif opts.cmd == 'subscriber_exists' and ( not opts.queue or not opts.client ):
|
||||
err('missing -q or -C')
|
||||
|
||||
return opts
|
||||
|
||||
class ConsumerHTMLParser(HTMLParser):
|
||||
'''
|
||||
Parse the consumers id from http://url/admin/queueConsumers.jsp?JMSDestination=QUEUENAME
|
||||
'''
|
||||
|
||||
consumers = []
|
||||
table = False
|
||||
body = False
|
||||
tr = False
|
||||
td = False
|
||||
a = False
|
||||
|
||||
def reset_vars(self):
|
||||
ConsumerHTMLParser.consumers = []
|
||||
ConsumerHTMLParser.table = False
|
||||
ConsumerHTMLParser.body = False
|
||||
ConsumerHTMLParser.tr = False
|
||||
ConsumerHTMLParser.td = False
|
||||
ConsumerHTMLParser.a = False
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if ConsumerHTMLParser.td and tag == 'a':
|
||||
ConsumerHTMLParser.a = True
|
||||
elif ConsumerHTMLParser.tr and tag == 'td':
|
||||
ConsumerHTMLParser.td = True
|
||||
elif ConsumerHTMLParser.body and tag == 'tr':
|
||||
ConsumerHTMLParser.tr = True
|
||||
elif ConsumerHTMLParser.table and tag == 'tbody':
|
||||
ConsumerHTMLParser.body = True
|
||||
elif tag == 'table':
|
||||
ConsumerHTMLParser.table = ('id', 'messages') in attrs
|
||||
|
||||
def handle_data(self, data):
|
||||
if ConsumerHTMLParser.a:
|
||||
tmp = data.split('-')[0]
|
||||
if not tmp in ConsumerHTMLParser.consumers:
|
||||
ConsumerHTMLParser.consumers.append( tmp )
|
||||
ConsumerHTMLParser.a = False
|
||||
ConsumerHTMLParser.td = False
|
||||
ConsumerHTMLParser.tr = False
|
||||
|
||||
def get_consumers(self):
|
||||
return ConsumerHTMLParser.consumers
|
||||
|
||||
|
||||
class ActivemqMonitor():
|
||||
'''
|
||||
Monitor ActiveMQ via http web interface
|
||||
'''
|
||||
|
||||
def __init__(self, server, port, timeout):
|
||||
self.url = 'http://{0}:{1}'.format(server, port)
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.timeout = timeout
|
||||
|
||||
def discovery(self, **kwargs):
|
||||
'''
|
||||
return a json of all the queues in the server
|
||||
'''
|
||||
ret = {"data": []}
|
||||
for q in ET.fromstring( urllib2.urlopen(self.url+'/admin/xml/queues.jsp', timeout=self.timeout).read() ).findall('queue'):
|
||||
ret['data'].append( {
|
||||
'{#ACTIVEMQ_Q}': q.get('name')
|
||||
}
|
||||
)
|
||||
return ret
|
||||
|
||||
def queue_prop(self, **kwargs):
|
||||
'''
|
||||
return the property of the queue in the server
|
||||
'''
|
||||
for q in ET.fromstring( urllib2.urlopen(self.url+'/admin/xml/queues.jsp', timeout=self.timeout).read() ).findall('queue'):
|
||||
if q.get('name') == kwargs['queue']:
|
||||
return int(q.find('stats').get(kwargs['data']))
|
||||
|
||||
return 'couldnt find the queue'
|
||||
|
||||
def subscriber_exists(self, **kwargs):
|
||||
'''
|
||||
check if the clientid is configured as a subscriber on the queue
|
||||
'''
|
||||
|
||||
url = '{0}/admin/queueConsumers.jsp?{1}'.format(
|
||||
self.url,
|
||||
urllib.urlencode( { 'JMSDestination': kwargs['queue'] } ),
|
||||
)
|
||||
consumer_parser = ConsumerHTMLParser()
|
||||
consumer_parser.feed( urllib2.urlopen(url, timeout=self.timeout).read() )
|
||||
|
||||
if kwargs['client'] in consumer_parser.get_consumers():
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
# Global Settings
|
||||
opts = prepareOpts()
|
||||
monitor = ActivemqMonitor( opts.server, opts.port, opts.timeout )
|
||||
k = {
|
||||
'queue': opts.queue,
|
||||
'data': opts.data,
|
||||
'client': opts.client,
|
||||
}
|
||||
|
||||
# Do the work
|
||||
method = getattr(monitor, opts.cmd)
|
||||
res = method(**k)
|
||||
if type(res) is dict:
|
||||
print json.dumps( res )
|
||||
else:
|
||||
print res
|
||||
21
zabbix/scripts/list_ips.py
Executable file
21
zabbix/scripts/list_ips.py
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
Uses the zabbix python api to retrieve a list the all servers names & ips
|
||||
|
||||
Need to configure the server, username & passwords settings
|
||||
'''
|
||||
|
||||
from zabbix_api import ZabbixAPI
|
||||
|
||||
server="https://url.of.zabbix.site"
|
||||
username="user of read on all hosts"
|
||||
password="pass"
|
||||
|
||||
zapi = ZabbixAPI(server=server, path="")
|
||||
zapi.login(username, password)
|
||||
|
||||
hosts=zapi.host.get({"selectInterfaces": "extend", "output": "extend"})
|
||||
for host in hosts:
|
||||
for int in host['interfaces']:
|
||||
print "{}\t{}".format(host['host'],host['interfaces'][int]['ip'])
|
||||
break
|
||||
57
zabbix/scripts/rss.py
Executable file
57
zabbix/scripts/rss.py
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python27
|
||||
|
||||
'''
|
||||
Info:
|
||||
This python script is used as an Zabbix alert script to create simple RSS feed
|
||||
of the notifications
|
||||
|
||||
To make it work:
|
||||
- Configure the Settings section in the script
|
||||
- add as an alert script in zabbix
|
||||
- notice that the subject won't be in the rss, only the message
|
||||
- add the xml code below to the rssFile
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<language>en</language>
|
||||
</channel>
|
||||
</rss>
|
||||
'''
|
||||
|
||||
# libs
|
||||
import xml.etree.ElementTree as ET
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
# Settings
|
||||
link_data = "https://path/to/zabbix/tr_status.php?form_refresh=1&groupid=0&hostid=0&fullscreen=1"
|
||||
rssFile = "/path/to/zabbix/web/interface/rss"
|
||||
item_2_keep = 20
|
||||
title_data = sys.argv[3]
|
||||
|
||||
# get root
|
||||
tree = ET.parse(rssFile)
|
||||
root = tree.getroot()
|
||||
|
||||
# update time
|
||||
root[0][4].text = str(datetime.datetime.now())
|
||||
|
||||
# add new item
|
||||
new_item = ET.SubElement(root[0],"item")
|
||||
title = ET.SubElement(new_item,"title")
|
||||
title.text = str(title_data)
|
||||
link = ET.SubElement(new_item,"link")
|
||||
link.text = str(link_data)
|
||||
|
||||
# keep only x latest items
|
||||
itemRoot = root[0]
|
||||
items = itemRoot.findall('item')
|
||||
i=0
|
||||
for item in items:
|
||||
i=i+1
|
||||
if i > len(items)-item_2_keep:
|
||||
break
|
||||
itemRoot.remove(item)
|
||||
|
||||
|
||||
# write to file
|
||||
tree.write(rssFile)
|
||||
65
zabbix/scripts/smx-bundle.py
Executable file
65
zabbix/scripts/smx-bundle.py
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
Info:
|
||||
check via ssh if a bundle is in Active mode
|
||||
in an Apache ServiceMix setup
|
||||
'''
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
# Functions
|
||||
def myShell(cmd):
|
||||
"""
|
||||
will execute the cmd in a Shell and will return the hash res
|
||||
res['out'] -> array of the stdout (bylines)
|
||||
res['err'] -> same as above only stderr
|
||||
res['exit'] -> the exit code of the command
|
||||
"""
|
||||
|
||||
res = {}
|
||||
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=None)
|
||||
tmp = proc.communicate()
|
||||
res['out'] = tmp[0].splitlines()
|
||||
res['err'] = tmp[1].splitlines()
|
||||
res['exit'] = proc.returncode
|
||||
return res
|
||||
|
||||
|
||||
# Parser
|
||||
parser = argparse.ArgumentParser(description="check via ssh-smx if the bundle is in Active mode in an Apache ServiceMix setup")
|
||||
parser.add_argument("srv", type=str, help="hostname or ip of the smx server")
|
||||
parser.add_argument("port", type=int, help="port of the smx daemon")
|
||||
parser.add_argument("user", type=str, help="servicemix username")
|
||||
parser.add_argument("passwd", type=str, help="servicemix password")
|
||||
parser.add_argument("bundle", type=str, help="bundle name")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Settings
|
||||
ssh = "timeout 3 sshpass -p "+str(args.passwd)+" ssh -l "+str(args.user)+" -o ConnectTimeout=3 -o StrictHostKeyChecking=no -p "+str(args.port)+" "+args.srv+" osgi:list"
|
||||
|
||||
# Start script
|
||||
output = myShell(ssh)
|
||||
if output['exit'] != 0:
|
||||
print 0
|
||||
exit(1)
|
||||
|
||||
output['out'].pop(0)
|
||||
output['out'].pop(0)
|
||||
|
||||
found = False
|
||||
for line in output['out']:
|
||||
if re.search('\[Active', line):
|
||||
linePars = line.split("]")
|
||||
name = linePars.pop()
|
||||
name.strip()
|
||||
if re.search(re.escape(args.bundle), name):
|
||||
found = True
|
||||
break
|
||||
|
||||
if found:
|
||||
print 1
|
||||
else:
|
||||
print 0
|
||||
|
||||
223
zabbix/scripts/solr.py
Executable file
223
zabbix/scripts/solr.py
Executable file
@@ -0,0 +1,223 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user