diff --git a/watcharnsberg b/watcharnsberg index b46b750..9f2f0c3 100755 --- a/watcharnsberg +++ b/watcharnsberg @@ -1,8 +1,8 @@ #!/usr/bin/env python -# $Id: watcharnsberg,v 1.3 2005/05/06 14:33:30 andreas Exp $ +# $Id: watcharnsberg,v 1.4 2005/05/06 14:34:00 andreas Exp $ # Wait for heartbeat messages and act on them (or their absence) # -import time, os, string, sys, socket, curses, atexit, select +import time, os, string, sys, socket, curses, atexit, select, SocketServer LOGF="/home/andreas/public_html/messages/andreas" @@ -11,6 +11,8 @@ hosts={} num=0 upcount=0 PORT=50003 +TPORT=50004 +THOST="10.99.1.4" DEBUG=False verbose=False @@ -28,17 +30,22 @@ msgwB=None msgwHeight=10 class Host: + up="up" + down="down" + overdue="overdue" + OVERDUE="OVERDUE" + def __init__(self, name, addr): global num self.name=name self.addr=addr self.num=num - self.last=time.time() + self.lastbeat=time.time() self.upcount=0 - self.up=1 + self.state=Host.up self.uppercent="n/a" self.state="up" - self.statetime=self.last + self.statetime=self.lastbeat self.interval=INTERVAL num+=1 @@ -50,10 +57,6 @@ class Host: 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 @@ -138,36 +141,36 @@ def initwin(): # # # -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) +def checkoverdue(): 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() + if hosts[h].state == Host.down: + continue + if hosts[h].state == Host.up and now-hosts[h].lastbeat > hosts[h].interval+GRACE: + hosts[h].newstate(Host.overdue) + elif hosts[h].state == Host.overdue and now-hosts[h].lastbeat > hosts[h].interval*5+GRACE: + log("%s is overdue" % h) + hosts[h].newstate(Host.OVERDUE) + +# +# +# +# +def displaytime(): + maxY,maxX=stdscr.getmaxyx() + stdscr.addstr(0,maxX-8, time.strftime("%H:%M:%S", time.localtime(now)), curses.A_BOLD) + + for h in hosts: + d=hosts[h].getstate() + attr=0 + if verbose and hosts[h].state != Host.down: + d=dur(now-hosts[h].lastbeat) + if hosts[h].state == Host.OVERDUE: + attr=curses.A_BOLD + win.addstr(hosts[h].num+1, 25, "%8s" % d, attr) + win.addstr(hosts[h].num+1, 53, "%3s" % hosts[h].uppercent ) + win.refresh() + stdscr.refresh() # # @@ -195,6 +198,7 @@ def displaybody(): displaystatetime(h, 0) win.refresh() + # # # @@ -212,8 +216,7 @@ def displaymsgs(): def display(): if visual: initwin() - displaytime() - if visual: + displaytime() displaybody() displaymsgs() @@ -239,10 +242,10 @@ def fromaddr(name, addr, boot): if not htab.has_key(addr): addhost(name, addr) host=hosts[htab[addr]] - host.last=now - if host.getstate() != "up": + host.lastbeat=now + if host.getstate() != Host.up: lasts=host.state - d=host.newstate("up") + d=host.newstate(Host.up) log("%s, back after being %s for %s" % (host.name, lasts, dur(d))) host.upcount+=1 @@ -280,24 +283,52 @@ def readsock(): if boot: log("%s booted" % name) if msg: - log("%s %s" % (name, msg),service=service) + 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].newstate(Host.down) hosts[name].interval=interval # # # -def dominute(): +def updatestats(): 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 genhtml(now): + f=open("/home/andreas/public_html/private/watcharnsberg.html","w") + f.write("") + f.write("") + f.write("\n" % 10) + f.write("") + f.write('') + f.write("

Heartbeat status at %s

" % time.strftime("%H:%M:%S", time.localtime(now))) + f.write("") + f.write("\n" ) + for h in hosts: + f.write("\n" % (h, hosts[h].state, hosts[h].addr, hosts[h].uppercent, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(hosts[h].statetime)))) + f.write("
HostStateIP AddrResLast change
%-24s%-7s%-16s%-3s%-17s
") + f.write("

") + for m in msgs[len(msgs)-30:]: + f.write("%s
" % m) + os.environ['SCRIPT_FILENAME']="/home/andreas/bin/watcharnsberg" + g=os.popen("/home/andreas/cgi-bin/trailer.py", "r") + o=g.readlines() + g.close() + f.write(string.join(o,"")) + f.close() + +# +# +# def initcurses(): @@ -312,12 +343,79 @@ def exitcurses(): curses.nocbreak(); stdscr.keypad(0); curses.echo() curses.endwin() +# +# +# +class HtmlHandler(SocketServer.BaseRequestHandler): + def handle(self): + f=self.request.makefile() + + while 1: + line=string.strip(f.readline()) + if len(line) == 0: + break + r=line.split() + if r[0] == "GET": + uri=r[1] + html=r[2] + if uri != "/": + code=404 + cause="Not Found" + else: + code=200 + cause="OK" + self.request.send("HTTP/1.0 %s %s\r\n" % (code, cause)) + self.request.send("Date: %s\r\n" % time.strftime("%a, %d %b %Y %H:%M:%S GMT",time.gmtime(now))) + self.request.send("Server: WatchArnsberg\r\n") + self.request.send("Last-Modified: %s\r\n" % time.strftime("%a, %d %b %Y %H:%M:%S GMT",time.gmtime(now))) + self.request.send("Accept-Ranges: bytes\r\n") + self.request.send("Connection: close\r\n") + self.request.send("Content-Type: text/html; charset=ISO-8859-1\r\n\r\n") + res=[] + if code != 200: + res.append('') + res.append('') + res.append('%s %s' % (code, cause)) + res.append('') + res.append('

%s

' % (cause)) + res.append('

The requested URL %s was not found on this server.

' % uri) + res.append('
') + res.append('
WatchArnsberg (Unix) Server at somewhere.planix.com Port %d
' % TPORT) + res.append('') + + else: + res.append('') + res.append("") + res.append("") + res.append("\n" % 60) + res.append("") + res.append('') + res.append("

Heartbeat status at %s

" % time.strftime("%H:%M:%S", time.localtime(now))) + res.append("") + res.append("\n" ) + for h in hosts: + res.append("\n" % (h, hosts[h].state, hosts[h].addr, hosts[h].uppercent, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(hosts[h].statetime)))) + res.append("
HostStateIP AddrResLast change
%-24s%-7s%-16s%-3s%-17s
") + res.append("

") + for m in msgs[len(msgs)-30:]: + res.append("%s
" % m) +# os.environ['SCRIPT_FILENAME']="/home/andreas/bin/watcharnsberg" +# g=os.popen("/home/andreas/cgi-bin/trailer.py", "r") +# o=g.readlines() +# g.close() +# res.append(string.join(o,"")) + + try: + self.request.send(string.join(res,"\n")) + except: + pass + + # # Main # - initlog() now=time.time() @@ -336,9 +434,11 @@ ilist=[] sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(("",PORT)) - ilist.append(sock) +serv=SocketServer.TCPServer((THOST,TPORT),HtmlHandler) +ilist.append(serv.fileno()) + next=int(now)+1 sleep=next - now while 1: @@ -358,7 +458,9 @@ while 1: sys.exit(0) except select.error, value: if value[0] != 4: # interrupted system call - raise os.error, value + print select.error, value + #raise os.error, value + continue if visual: exitcurses() initcurses() @@ -367,18 +469,23 @@ while 1: for fh in sr[0]: if fh == sock: readsock() + if fh == serv.fileno(): + serv.handle_request() if now >= next: - next+=1 + next=now+1 if int(now) % INTERVAL == startsec: - dominute() + updatestats() +## if int(now) % 60 == 0: +## genhtml(now) + checkoverdue() 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() + stdscr.move(1 , 0) + stdscr.clrtoeol() + displaytime() + sleep=next-now + if sleep < 0: + sys.stderr.write("sleep is negaitive! %s next=%s\n" % (sleep, next)) + sleep=0 if DEBUG: sys.stderr.write("sleep=%s next=%s\n" % (sleep, next))