Skip to content

Instantly share code, notes, and snippets.

@iMilnb
Last active February 11, 2022 08:24
Show Gist options
  • Save iMilnb/ed806a900606df1895ef to your computer and use it in GitHub Desktop.
Save iMilnb/ed806a900606df1895ef to your computer and use it in GitHub Desktop.
Fetch monit XML status URL content, transform it to JSON and display a status report
#!/usr/bin/env python
import requests
import xmltodict
import json
import os
import sys
with open('{0}/.getmonitrc'.format(os.path.expanduser('~'))) as f:
cf = json.loads(f.read())
red = u'\033[1;31m'
green = u'\033[1;32m'
okkomatch = [
{ 'bold': u'\u2714', 'normal': u'\t\u2713' },
{ 'bold': u'\u2718', 'normal': u'\t\u2717' }
]
color = [ green , red ]
if len(sys.argv) > 1:
arg = sys.argv[1]
else:
arg = ''
def okko_print(okko, bold, text):
if okko != 0: okko = 1
sys.stdout.write(color[okko])
sys.stdout.write(okkomatch[okko][bold])
# restore normal color
sys.stdout.write('\033[1;0m')
print(' {0}'.format(text))
def check_status(item):
if float(item['responsetime']) < 0.0:
return -1
else:
return 0
globstatus = 0
for site in cf:
s = cf[site]
r = requests.get(s['url'], auth=(s['user'], s['passwd']))
allstat = json.loads(json.dumps(xmltodict.parse(r.text)['monit']))
services = allstat['service']
status = {}
if arg and arg == 'dump':
print(json.dumps(allstat))
sys.exit(0)
for service in services:
name = service['name']
status[name] = { 'status': int(service['status']), 'check': {} }
if 'icmp' in service:
status[name]['check']['icmp'] = {
'status': check_status(service['icmp'])
}
if 'port' in service:
if type(service['port']) is not list:
service['port'] = [service['port']]
status[name]['check']['port'] = {}
for port in service['port']:
portnum = port['portnumber']
status[name]['check']['port'][portnum] = {
'responsetime': port['responsetime'],
'protocol': port['protocol'],
'type': port['type'],
'hostname': port['hostname'],
'status': check_status(port)
}
if status[name]['status'] != 0:
globstatus = '-1'
# display
if 'v' in arg:
okko_print(status[name]['status'], 'bold', name)
if 'vv' in arg and 'check' in status[name]:
for check in status[name]['check']:
if 'icmp' in check:
okko_print(
status[name]['check']['icmp']['status'],
'normal',
'icmp'
)
if 'port' in check:
for port in status[name]['check']['port']:
okko_print(
status[name]['check']['port'][port]['status'],
'normal',
'port {0}/{1}'.format(
port,
status[name]['check']['port'][port]['protocol']
)
)
if not arg:
okko_print(globstatus, 'bold', 'global status')
@foxmask
Copy link

foxmask commented Feb 11, 2022

Hi,
years later ;)

i made a use case where, instead of going to grab data from a monitored VM where monit is started...
I made a hook which receive data from the monitored VM like that

PAYLOAD=$(curl -XGET http://$MONIT_ADMIN:$MONIT_ADMIN_PASS@$MONIT_SERVER:2812/_status?format=xml -H "Accept: application/xml") && curl -s -XPOST --data-binary "$PAYLOAD" $URL -H "Content-Type: application/xml" -H "Accept: application/xml"

then, when the data are receive on the server part I enchain with

allstat = json.loads(json.dumps(xmltodict.parse(r.text)['monit']))

Or if I want to send just the status of ONE probe I did

PAYLOAD="{\"data_collected\": \"${MONIT_TIMESTAMP}\", \"server\": \"${MONIT_HOST}\", \"service\": \"${SERVICE}\", \"status_string\": \"${MONIT_DESCRIPTION}\" , \"status\": \"${STATUS}\", \"type\": \"server\"}"
curl -s -X POST --data-urlencode "$PAYLOAD" $URL

cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment