#!/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()