diff options
-rw-r--r-- | tools/check-flimsy.py | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/tools/check-flimsy.py b/tools/check-flimsy.py new file mode 100644 index 0000000..8d33d9e --- /dev/null +++ b/tools/check-flimsy.py @@ -0,0 +1,205 @@ +#!/usr/bin/python + +import urllib2 +import json +import socket +import datetime +import sys +import time +import smtplib +import atexit +import socket +import signal +from email.mime.text import MIMEText + + +def dump(obj): + for attr in dir(obj): + print "obj.%s = %s" % (attr, getattr(obj, attr)) + + +def testurl(url, timeout): + """ + returns a list, which first item is status, and optional second item is extra information, like: + ['ok'] + of + ['other', 'overheating'] + status: + 'ok' - check ok + 'head too old': arg = time diff in seconds + 'connection refused' + 'connection timeout' + 'response timeout' + 'other': arg = error string - other unknown errors + + """ + + try: + f = urllib2.urlopen(url, timeout=timeout) + now = datetime.datetime.utcnow() + obj = json.load(f) + if 'timestamp' in obj: + x = datetime.datetime.utcfromtimestamp(obj['timestamp'] / 1000) + datetime.timedelta(milliseconds = obj['timestamp'] % 1000) + secs = (now - x).total_seconds() + if secs > 7200: + return ['head too old', secs] + return ['ok'] + return ['other', 'no timestamp in reply'] + + except urllib2.URLError as e: + #print 'except urllib2.URLError' + #print repr(e.reason) + + reason_type = type(e.reason).__name__ + + if reason_type == 'error': + err_str = e.args[0].strerror + if err_str == 'Connection refused': + return ['connection refused'] + else: + return ['other', str(e)] + + elif reason_type == 'timeout': + # timeout when connecting + return ['connection timeout'] + + else: + return ['other', str(e)] + + except IOError as e: + #print 'except IOError' + + if type(e).__name__ == 'timeout': + # timeout when reading + return ['response timeout'] + + else: + return ['other', str(e)] + + except: + return ['other', str(sys.exc_info()[0])] + + +""" + print repr(type(e.reason).__name__) + print 'repr(e) ', repr(e) + print 'e ', e + print 'e.args ', e.args + print 'e.errno ', e.errno + print 'e.strerror ', e.strerror + dump(e) + print 'repr(e.args[0]) ', repr(e.args[0]) + dump (e.args[0]) + + +""" + +myhostname = None + +def sendmsg(newstate, state, l, lastchange, adminonly=False): + global myhostname + if not myhostname: + myhostname = socket.gethostname() + + txt = 'checkflimsy on %s\n' % (myhostname) + txt += 'state: %s\n' % newstate + if newstate == 'head too old': + txt += 'head too old: %f seconds\n' % l[1] + if newstate == 'other': + txt += 'message: %s\n' % str(l[1]) + txt += 'last state change: %s\n' % lastchange.replace(microsecond=0).isoformat(' ') + delta = datetime.datetime.now().replace(microsecond=0) - lastchange.replace(microsecond=0) + txt += 'time since last state change: %s\n' % str(delta) + txt += '(previous state: %s)\n' % state + + print txt # XXX + + msg = MIMEText(txt) + + fromaddr = 'foo-admin@example.net' + toaddrs = ['foo@example.net'] + if adminonly: + toaddrs = ['foo@example.net'] + + + subj = '%s flimsy status: %s' % (myhostname, newstate) + if newstate == 'other': + subj += ' - %s' % str(l[1]) + if newstate not in ['ok', 'starting']: + subj += ' - WARNING' + msg['Subject'] = subj + msg['From'] = fromaddr + msg['To'] = ', '.join(toaddrs) + + # Send the message via our own SMTP server, but don't include the + # envelope header. + s = smtplib.SMTP('localhost') + s.sendmail(fromaddr, toaddrs, msg.as_string()) + s.quit() + + +lastchange = None +state = None + +def runloop(url): + timeout = 10 + sleeptime = 30 + repeattime = 7200 + lasttold = None + global lastchange + global state + + while True: + #print '.' # XXX + l = testurl(url, timeout) + newstate = l[0] + + now = datetime.datetime.now() + + if state != newstate: + lastchange = now + lasttold = now + if state == None: + # starting + print 'check-flimsy started at %s' % (str(now)) + sendmsg('starting', state, l, lastchange, adminonly=True) + else: + sendmsg(newstate, state, l, lastchange) + state = newstate + elif state != 'ok' and (now - lasttold) > datetime.timedelta(seconds=repeattime): + lasttold = now + sendmsg(newstate, state, l, lastchange) + + time.sleep(sleeptime) + + +""" + 'ok' - check ok + 'head too old': arg = time diff in seconds + 'connection refused' + 'connection timeout' + 'response timeout' + 'other': arg = error string - other unknown errors +""" + + +def exitproc(): + sendmsg('EXITING', state, ['-'], lastchange, adminonly=True) + + +def main(): + url = 'https://flimsy.ct.nordu.net:8080/ct/v1/get-sth' + #url = 'http://127.0.0.1:8080' + + while True: + try: + atexit.register(exitproc) + signal.signal(signal.SIGHUP, exitproc) + + runloop(url) + except: + print "Unexpected error from runloop():", sys.exc_info()[0] + raise # XXX + + +main() |