diff --git a/hbc b/hbc index cb30a60..abe2b4d 100755 --- a/hbc +++ b/hbc @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $ # NEW import sys @@ -11,7 +11,7 @@ import string import select import errno import traceback -import md5 +from hashlib import md5 import shutil import zlib import subprocess @@ -35,7 +35,7 @@ def log(msg): if fdaemon: syslog.syslog(syslog.LOG_ERR, msg) else: - print msg + print(msg) def handler(signum, frame): if signum == signal.SIGTERM: @@ -82,7 +82,7 @@ class Conn: msg['id'] = self.conId msg['ver'] = VER msg['time'] = time.time() - m = dicttos(ID, msg, True) # always compress + m = dicttos(ID, msg) # always compress if verbose: log("conn.send('%s', (%s:%s) %s)" % (msg, self.addr, self.port, len(m))) try: @@ -93,14 +93,20 @@ class Conn: self.close() return self.send += 1 - self.lastsend = time.time() + self.lastsend = msg['time'] + print("RTT self.lastsend %s" % self.lastsend) - def ack(self, msgDict): - self.lastack = time.time() - self.lastacksent = float(msgDict.get('time','0')) - if verbose: log("ack RTT: %0.1f ms" % ((self.lastack - self.lastsend) * 1000.0)) - self.rtts.append((self.lastack - self.lastsend) * 1000.0) + def ack(self, msgDict, now): + try: + self.lastack = msgDict['time'] + mul = 2 + except: + self.lastack = now + mul = 1 + rtt = (self.lastack - self.lastsend) * mul + if verbose: log("ack RTT: %0.1f ms (now %s)" % (rtt * 1000.0, now)) + self.rtts.append(rtt * 1000.0) if len(self.rtts) > 10: del self.rtts[0] self.ackcount += 1 @@ -113,11 +119,11 @@ class Conn: def shortname(name): - r = string.split(name, '.') + r = name.split('.') return r[0] -def dicttos(ID, d, compress=False): +def dicttos(ID, d): s = [] for k in d: if type(d[k]) == type(1.2): @@ -125,15 +131,35 @@ def dicttos(ID, d, compress=False): else: s.append("%s=%s" % (k, d[k])) pk = ";".join(s) - if compress: - zpk = zlib.compress(pk, 6) - ID = "!"+ID - else: - zpk = pk - return ID + ":" + zpk - + zpk = zlib.compress(pk.encode(), 6) + ID = "!" + ID + ":" + return ID.encode() + zpk def stodict(msg): + d = {} + if len(msg) > 0 and chr(msg[0]) == "!": + pk = zlib.decompress(msg[5:]).decode() + d['ID'] = msg[1:4].decode() + else: + r0 = msg.split(':',1) + pk = r0[1] + d['ID'] = r0[0] + r = pk.split(';') + for v in r: + vr = v.split('=', 1) + k = vr[0].strip() + if len(vr) == 1: + d[k] = None + else: + v = vr[1].strip() + if v[0].isdigit(): + v = eval(v) + d[k] = v + print("DBG: msg is %s" % d) + return d + + +def XXstodict(msg): d = {} r0 = msg.split(':',1) if len(r0) == 1: @@ -167,7 +193,7 @@ def syslogtrace(note): for l in logm.split('\n'): syslog.syslog(syslog.LOG_ERR, ' tb: %s' % l) if verbose: - print logm + print(logm) conId = 1 @@ -188,13 +214,13 @@ def createConnections(hosts): elif r[0] == 2: af=socket.AF_INET else: - print "dont know this net type: %s" % r[0][0] + print("dont know this net type: %s" % r[0][0]) sys.exit(1) addr = r[4][0] conns[conId] = Conn(conId, addr, hb_port, af) if verbose: - print "cons[%s] = %s" % (conId, str(conns[conId])) + print("cons[%s] = %s" % (conId, str(conns[conId]))) conId += 1 @@ -258,14 +284,14 @@ def doupdateone(code, csum): def restart(): if verbose: - print "restart: execv %s %s" % (sys.argv[0], [sys.argv[0]]+cmdargs) + print("restart: execv %s %s" % (sys.argv[0], [sys.argv[0]]+cmdargs)) syslog.syslog(syslog.LOG_ERR, 'restart %s' % (sys.argv[0])) e = "fallthrough" try: os.execv(sys.argv[0], [sys.argv[0]]+cmdargs) except Exception as e: pass - print "should not be here:", str(e) + print("should not be here:", str(e)) log('restart failed: %s' % e) @@ -287,7 +313,8 @@ def process(): if sleep <= 0: break try: - r=select.select(ifiles.keys(),[],[],sleep) + r=select.select(list(ifiles.keys()),[],[],sleep) + now = time.time() # nb: delay from actual packet arrival to select is ca. 105ms! except KeyboardInterrupt: running = False break @@ -304,16 +331,16 @@ def process(): for rfh in r[0]: conn = conIds[rfh] data, addr = ifiles[rfh].recvfrom(MAXRECV) - if verbose: print "sock.recvfrom: %s (%s) %s" % (addr, len(data), data[:4]) +# if verbose: print("sock.recvfrom: %s (%s) %s" % (addr, len(data), data[:4])) msgDict = stodict(data) - if verbose: print "sock.recvfrom: %s (%s) %s" % (addr, len(data), str(msgDict)[:80]) + if verbose: print("sock.recvfrom: %s (%s) %s" % (addr, len(data), str(msgDict)[:80])) if msgDict == None: - print "bad backet from %s (%s) %s" % (addr, len(data), data) + print("bad backet from %s (%s) %s" % (addr, len(data), data)) elif msgDict['ID'] == "ACK": - conns[conn].ack(msgDict) + conns[conn].ack(msgDict, now) elif msgDict['ID'] == "UPD": if doupdate(conn, msgDict) == None: - if verbose: print "process: restart after update" + if verbose: print("process: restart after update") dorestart = True break elif msgDict['ID'] == "CMD": @@ -369,7 +396,7 @@ def daemonize(working_dir="/", stdin='/dev/zero', stdout='/dev/null', stderr='/d if pid > 0: # exit from first parent os._exit(0) - except OSError, e: + except OSError as e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) os._exit(1) @@ -383,7 +410,7 @@ def daemonize(working_dir="/", stdin='/dev/zero', stdout='/dev/null', stderr='/d if pid > 0: # exit from second parent os._exit(0) - except OSError, e: + except OSError as e: sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) @@ -438,20 +465,20 @@ for o,a in optlist: cmdargs += args -if verbose: print "cmdargs for restart are %s" % cmdargs +if verbose: print("cmdargs for restart are %s" % cmdargs) if helpflag: - print "hbc HeartBeatClient" - print "usage: hbc [-bdhv] [-c configfile] [-m msg][host1 [..]]" - print - print " -b indicate machine boot" - print " -c configfile" - print " -d daemonize" - print " -h this help" - print " -m send a message" - print " -v verbose" - print - print """ config file can contain + print("hbc HeartBeatClient") + print("usage: hbc [-bdhv] [-c configfile] [-m msg][host1 [..]]") + print() + print(" -b indicate machine boot") + print(" -c configfile") + print(" -d daemonize") + print(" -h this help") + print(" -m send a message") + print(" -v verbose") + print() + print(""" config file can contain hb_hosts=('host1', 'host2', ..._ hb_port=50003 interval=20 @@ -459,7 +486,7 @@ logfile=... logfmt={|test|msg} grace=SECONDS reportstrict={True|False} -""" +""") sys.exit(1) @@ -473,9 +500,9 @@ iam=socket.gethostname() try: f=open(configfile,"r") - if verbose: print "notice: using config file %s" % configfile + if verbose: print("notice: using config file %s" % configfile) except: - if verbose: print "warning: running without config file: %s" % configfile + if verbose: print("warning: running without config file: %s" % configfile) f=None if f: @@ -487,14 +514,14 @@ if f: if r[0] == 'hb_hosts': hb_hosts=eval(r[1]) if verbose: - print "notice: cfg hb_hosts: %s" % hb_hosts + print("notice: cfg hb_hosts: %s" % hb_hosts) elif r[0] == 'interval': interval=eval(r[1]) elif r[0] == 'hb_port': hb_port=eval(r[1]) elif r[0] == 'name': iam=eval(r[1]) - if verbose: print "name set to %s" % iam + if verbose: print("name set to %s" % iam) f.close() if len(args) != 0: @@ -502,17 +529,17 @@ if len(args) != 0: if len(hb_hosts) == 0: - print "no hb server specified" + print("no hb server specified") sys.exit(1) # if verbose: - print "notice: hb_hosts: %s" % str(hb_hosts) - print "notice: hb_port: %s" % hb_port - print "notice: interval: %s" % interval - print "notice: iam: %s" % iam - print "notice: msgonly: %s" % msgonly - print "notice: msgboot: %s" % msgboot + print("notice: hb_hosts: %s" % str(hb_hosts)) + print("notice: hb_port: %s" % hb_port) + print("notice: interval: %s" % interval) + print("notice: iam: %s" % iam) + print("notice: msgonly: %s" % msgonly) + print("notice: msgboot: %s" % msgboot) if not msgonly: msgboot['interval'] = interval @@ -531,20 +558,20 @@ if verbose: log("%s connections created" % (len(conns))) if len(msgboot) > 0: - if verbose: print "on boot" + if verbose: print("on boot") msgboot['acks'] = 0 for conn in conns: conns[conn].sendto(msgboot) if msgonly: - if verbose: print "msgboot done msgonly=%s" % msgonly + if verbose: print("msgboot done msgonly=%s" % msgonly) closeall() sys.exit(0) # syslog.openlog('hbc', syslog.LOG_PID, syslog.LOG_DAEMON) if fdaemon: - print "daemoinizing." + print("daemoinizing.") daemonize() daemonized = True syslog.syslog(syslog.LOG_ERR, 'starting heartbeat to %s' % ','.join(hb_hosts)) @@ -555,7 +582,7 @@ try: process() except: syslogtrace('process') - if verbose: print "err: process exit: %s" % e + if verbose: print("err: process exit: %s" % e) if verbose: log( "main: cleanup") cleanup()