From 777b50e4e93f26abff47128a7c5b9efae4821d37 Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 27 Feb 2005 16:39:35 +0000 Subject: [PATCH] Initial revision --- heartbeat | 48 +++++++ heartbeatmsg | 15 ++ watcharnsberg | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 446 insertions(+) create mode 100755 heartbeat create mode 100755 heartbeatmsg create mode 100755 watcharnsberg diff --git a/heartbeat b/heartbeat new file mode 100755 index 0000000..40104ae --- /dev/null +++ b/heartbeat @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +import sys, time, socket, os, signal + +ADDR="204.29.161.33" +#ADDR="10.99.1.4" +PORT=50003 +INTERVAL=10 + +def handler(signum, frame): + global up + if signum == 1: + os.execv("/usr/bin/env", ["python", sys.argv[0],"relaunch"]) + if up == 0: + return + sys.exit(0) +iam=socket.gethostname() +sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +msg="interval=%s;name=%s" % (INTERVAL, iam) + +if len(sys.argv) <= 1 or sys.argv[1] != "relaunch": + msgboot="boot=1;interval=%s;name=%s" % (INTERVAL, iam) + while 1: + try: + sock.sendto(msgboot, (ADDR, PORT)) + break + except: + time.sleep(10) + +up=1 +signal.signal(signal.SIGTERM, handler) +signal.signal(signal.SIGHUP, handler) + +while up: + try: + time.sleep(10) + except: + break + try: + sock.sendto(msg, (ADDR, PORT)) + except: + pass + +up=0 +msg="shutdown=1;name=%s" % (iam) +sock.sendto(msg, (ADDR, PORT)) +time.sleep(1) +sock.close() diff --git a/heartbeatmsg b/heartbeatmsg new file mode 100755 index 0000000..0661bdd --- /dev/null +++ b/heartbeatmsg @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import time, socket + +ADDR="204.29.161.33" +#ADDR="10.99.1.4" +PORT=50003 +SERVICE="service" + +iam=socket.gethostname() +sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +msgboot="msg=This is a test;service=%s;name=%s" % (SERVICE, iam) +sock.sendto(msgboot, (ADDR, PORT)) +time.sleep(1) +sock.close() diff --git a/watcharnsberg b/watcharnsberg new file mode 100755 index 0000000..b240569 --- /dev/null +++ b/watcharnsberg @@ -0,0 +1,383 @@ +#!/usr/bin/env python +# watch all ip addresses for Telekom in Arnsberg for a icmp packet +# +import time, os, string, sys, socket, curses, atexit, select + + +LOGF="/home/andreas/public_html/messages/andreas" + +hosts={} +num=0 +upcount=0 +PORT=50003 +DEBUG=False +verbose=False + +INTERVAL=10 +GRACE=10 + +visual=0 + +msgs=[] + +stdscr=None +win=None +msgw=None +msgwB=None +msgwHeight=10 + +class Host: + def __init__(self, name, addr): + global num + self.name=name + self.addr=addr + self.num=num + self.last=time.time() + self.upcount=0 + self.up=1 + self.uppercent="n/a" + self.state="up" + self.statetime=self.last + self.interval=INTERVAL + num+=1 + + def getstate(self): + return self.state + + def newstate(self, state): + self.state=state + now=time.time() + s=now-self.statetime + self.statetime=now + if state == "up": + self.up=1 + elif state == "down": + self.up=0 + if visual: + displaystatetime(self.name) + return s + + +# +# +def dur(sec): + sec=int(sec) + h=sec / 3600 + m=(sec - h * 3600) / 60 + s=(sec - h * 3600) % 60 + if h > 0: + return "%d:%02d:%02d" % (h, m, s) + if m > 0: + return "%d:%02d" % (m, s) + return "0:%02d" % s + + +# +# +# +def addhost(name, addr): + if hosts.has_key(name): + del htab[hosts[name].addr] + hosts[name].addr=addr + if visual: + displayaddr(name) + htab[addr]=name + log("%s, changed address to %s" % (name, addr)) + else: + hosts[name]=Host(name, addr) + s=hosts.keys() + s.sort() + x=0 + for n in s: + hosts[n].num=x + x+=1 + htab[addr]=name + if visual: + display() + +# +# +# +def on_exit(): + if visual: + exitcurses() + logf.close() + print "exit" + + +def initlog(): + global logf + logf=open(LOGF,"a") +# +# +# +def initwin(): + global win, msgw, msgwB, msgwHeight + + maxY,maxX=stdscr.getmaxyx() + + begin_x = 0 + begin_y = 2 + height = len(htab)+2 + if DEBUG: log("initwin called with %d" % height) + win = curses.newwin(height, maxX, begin_y, begin_x) + a=win.border(0,0,0,0,0,0,curses.ACS_LTEE,curses.ACS_RTEE) + + msgwB = curses.newwin(0, 0, height+1, begin_x) + msgwB.border(0,0,0,0,curses.ACS_LTEE,curses.ACS_RTEE) + + msgwHeight=maxY-height-3 + msgw = curses.newwin(msgwHeight, maxX-2, height+2, begin_x+1) + msgw.setscrreg(0, msgwHeight-1) + msgw.scrollok(1) + + stdscr.addstr(0,0, "WatchArnsberg Version 1.0", curses.A_BOLD) + stdscr.refresh() + msgwB.refresh() +# +# +# +def displaytime(): + if visual: + maxY,maxX=stdscr.getmaxyx() + stdscr.addstr(0,maxX-8, time.strftime("%H:%M:%S", time.localtime(now)), curses.A_BOLD) +# stdscr.addstr(0,67,"%s.%04d" % (time.strftime("%H:%M:%S", time.localtime(now)),int((now-int(now))*10000) ), curses.A_BOLD) + + for h in hosts: + if hosts[h].last != 0: + attr=0 + if verbose: + d=dur(now-hosts[h].last) + else: + d=hosts[h].getstate() + if not hosts[h].up: + d=hosts[h].getstate() + elif now-hosts[h].last > hosts[h].interval+GRACE: + d="overdue" + if now-hosts[h].last > hosts[h].interval*5+GRACE: + d="OVERDUE" + if hosts[h].getstate() != "overdue": + log("%s is overdue" % h) + hosts[h].newstate("overdue") + if now-hosts[h].last > hosts[h].interval*60+GRACE: + attr=curses.A_BOLD + if visual: + win.addstr(hosts[h].num+1, 25, "%8s" % d, attr) + win.addstr(hosts[h].num+1, 53, "%3s" % hosts[h].uppercent ) + if visual: + win.refresh() + stdscr.refresh() + +# +# +# +def displaystatetime(h, refresh=1): + win.addstr(hosts[h].num+1, 60, "%-17s" % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(hosts[h].statetime))) + if refresh: + win.refresh() +# +# +# +def displayaddr(h, refresh=1): + win.addstr(hosts[h].num+1, 35, "%-16s" % hosts[h].addr) + if refresh: + win.refresh() +# +# +# +def displaybody(): + for h in hosts: + win.addstr(hosts[h].num+1, 1, "%-24s" % (h)) + if hosts[h].addr != None: + displayaddr(h, 0) + if hosts[h].statetime != None: + displaystatetime(h, 0) + win.refresh() + +# +# +# +def displaymsgs(): + global msgw, msgs + y=0 + for m in msgs[len(msgs)-msgwHeight:]: + msgw.addstr(y, 0, m) + y+=1 + msgw.refresh() + +# +# +# +def display(): + if visual: + initwin() + displaytime() + if visual: + displaybody() + displaymsgs() + +def log(m, service="heartbeat"): + msg=time.strftime("%b %d %H:%M:%S")+": "+m+"\n" + msgs.append(msg) + m2="%d|%s|%s\n" % (now, service, m) + logf.write(m2) + logf.flush() + if msgw != None: + y,x=msgw.getyx() +# if y >= msgwHeight-1: +# msgw.scroll() + msgw.addstr(msg) + msgw.clrtoeol() + msgw.refresh() + +# +# +def fromaddr(name, addr, boot): + global htab + + if not htab.has_key(addr): + addhost(name, addr) + host=hosts[htab[addr]] + host.last=now + if host.getstate() != "up": + lasts=host.state + d=host.newstate("up") + log("%s, back after being %s for %s" % (host.name, lasts, dur(d))) + host.upcount+=1 + +# +# +# +def readsock(): + global htab, win + data, addr = sock.recvfrom(1024) + pairs=string.split(data,';') + boot=0 + shutdown=0 + name="unknown" + msg=None + interval=INTERVAL + for pair in pairs: + l=string.split(pair,"=") + key=l[0] + if len(l) != 2: + val="0" + else: + val=l[1] + if key == 'boot': + boot+=1 + elif key == 'shutdown': + shutdown+=1 + elif key == 'interval': + interval=int(val) + elif key == 'name': + name=val + elif key == 'msg': + msg=val + elif key == 'service': + service=val + if boot: + log("%s booted" % name) + if msg: + log("%s msg: %s" % (name, msg),service=service) + fromaddr(name, addr[0], boot) + if shutdown: + log("%s shutdown" % name) + hosts[name].newstate("down") + hosts[name].interval=interval + + +# +# +# +def dominute(): + global upcount + upcount+=1 + + for h in hosts: + if upcount > 0: + hosts[h].uppercent="%3.0f" % ((hosts[h].upcount*hosts[h].interval*100.0)/(upcount*INTERVAL)) + + +def initcurses(): + global stdscr + stdscr = curses.initscr() + curses.noecho() + curses.cbreak() + stdscr.keypad(1) + if DEBUG: sys.stderr.write("curses init done: %s\n" % stdscr) + +def exitcurses(): + curses.nocbreak(); stdscr.keypad(0); curses.echo() + curses.endwin() + +# +# Main +# + + + +initlog() + +now=time.time() +startsec=int(now) % INTERVAL + +htab={} +if visual: + initcurses() + display() + stdscr.nodelay(1) + +atexit.register(on_exit) +if DEBUG: log("Starting") + +ilist=[] + +sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sock.bind(("",PORT)) + +ilist.append(sock) + +next=int(now)+1 +sleep=next - now +while 1: + if visual: + c = stdscr.getch() + if c == ord('c'): msgs=[]; display() + elif c == ord('q'): break # Exit the while() + elif c == ord('d'): DEBUG=not DEBUG + elif c == ord('v'): verbose=not verbose +# elif c == ord('p'): PrintDocument() +# elif c == ord('x'): x = y = 0 + + try: + sr=select.select(ilist,[],[],sleep) + now=time.time() + except KeyboardInterrupt: + sys.exit(0) + except select.error, value: + if value[0] != 4: # interrupted system call + raise os.error, value + if visual: + exitcurses() + initcurses() + display() + continue + for fh in sr[0]: + if fh == sock: + readsock() + if now >= next: + next+=1 + if int(now) % INTERVAL == startsec: + dominute() + if visual: +# stdscr.addstr(1 , 0, "Now is %s, Next is %s" % (now, next)) + if DEBUG: + stdscr.addstr(1 , 0, "len(htab) is %s, Next is %s" % (len(htab), next)) + else: + stdscr.move(1 , 0) + stdscr.clrtoeol() + displaytime() + sleep=next-now + if DEBUG: sys.stderr.write("sleep=%s next=%s\n" % (sleep, next)) +