add http support

This commit is contained in:
andreas
2005-05-06 14:34:00 +00:00
parent f2dde884c5
commit 42409b1194
+165 -58
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env python #!/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) # 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" LOGF="/home/andreas/public_html/messages/andreas"
@@ -11,6 +11,8 @@ hosts={}
num=0 num=0
upcount=0 upcount=0
PORT=50003 PORT=50003
TPORT=50004
THOST="10.99.1.4"
DEBUG=False DEBUG=False
verbose=False verbose=False
@@ -28,17 +30,22 @@ msgwB=None
msgwHeight=10 msgwHeight=10
class Host: class Host:
up="up"
down="down"
overdue="overdue"
OVERDUE="OVERDUE"
def __init__(self, name, addr): def __init__(self, name, addr):
global num global num
self.name=name self.name=name
self.addr=addr self.addr=addr
self.num=num self.num=num
self.last=time.time() self.lastbeat=time.time()
self.upcount=0 self.upcount=0
self.up=1 self.state=Host.up
self.uppercent="n/a" self.uppercent="n/a"
self.state="up" self.state="up"
self.statetime=self.last self.statetime=self.lastbeat
self.interval=INTERVAL self.interval=INTERVAL
num+=1 num+=1
@@ -50,10 +57,6 @@ class Host:
now=time.time() now=time.time()
s=now-self.statetime s=now-self.statetime
self.statetime=now self.statetime=now
if state == "up":
self.up=1
elif state == "down":
self.up=0
if visual: if visual:
displaystatetime(self.name) displaystatetime(self.name)
return s return s
@@ -138,36 +141,36 @@ def initwin():
# #
# #
# #
def displaytime(): def checkoverdue():
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: for h in hosts:
if hosts[h].last != 0: if hosts[h].state == Host.down:
attr=0 continue
if verbose: if hosts[h].state == Host.up and now-hosts[h].lastbeat > hosts[h].interval+GRACE:
d=dur(now-hosts[h].last) hosts[h].newstate(Host.overdue)
else: elif hosts[h].state == Host.overdue and now-hosts[h].lastbeat > hosts[h].interval*5+GRACE:
d=hosts[h].getstate() log("%s is overdue" % h)
if not hosts[h].up: hosts[h].newstate(Host.OVERDUE)
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": def displaytime():
log("%s is overdue" % h) maxY,maxX=stdscr.getmaxyx()
hosts[h].newstate("overdue") stdscr.addstr(0,maxX-8, time.strftime("%H:%M:%S", time.localtime(now)), curses.A_BOLD)
if now-hosts[h].last > hosts[h].interval*60+GRACE:
attr=curses.A_BOLD for h in hosts:
if visual: d=hosts[h].getstate()
win.addstr(hosts[h].num+1, 25, "%8s" % d, attr) attr=0
win.addstr(hosts[h].num+1, 53, "%3s" % hosts[h].uppercent ) if verbose and hosts[h].state != Host.down:
if visual: d=dur(now-hosts[h].lastbeat)
win.refresh() if hosts[h].state == Host.OVERDUE:
stdscr.refresh() 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) displaystatetime(h, 0)
win.refresh() win.refresh()
# #
# #
# #
@@ -212,8 +216,7 @@ def displaymsgs():
def display(): def display():
if visual: if visual:
initwin() initwin()
displaytime() displaytime()
if visual:
displaybody() displaybody()
displaymsgs() displaymsgs()
@@ -239,10 +242,10 @@ def fromaddr(name, addr, boot):
if not htab.has_key(addr): if not htab.has_key(addr):
addhost(name, addr) addhost(name, addr)
host=hosts[htab[addr]] host=hosts[htab[addr]]
host.last=now host.lastbeat=now
if host.getstate() != "up": if host.getstate() != Host.up:
lasts=host.state 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))) log("%s, back after being %s for %s" % (host.name, lasts, dur(d)))
host.upcount+=1 host.upcount+=1
@@ -280,24 +283,52 @@ def readsock():
if boot: if boot:
log("%s booted" % name) log("%s booted" % name)
if msg: if msg:
log("%s %s" % (name, msg),service=service) log("%s msg: %s" % (name, msg),service=service)
fromaddr(name, addr[0], boot) fromaddr(name, addr[0], boot)
if shutdown: if shutdown:
log("%s shutdown" % name) log("%s shutdown" % name)
hosts[name].newstate("down") hosts[name].newstate(Host.down)
hosts[name].interval=interval hosts[name].interval=interval
# #
# #
# #
def dominute(): def updatestats():
global upcount global upcount
upcount+=1 upcount+=1
for h in hosts: for h in hosts:
if upcount > 0: if upcount > 0:
hosts[h].uppercent="%3.0f" % ((hosts[h].upcount*hosts[h].interval*100.0)/(upcount*INTERVAL)) 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("<html>")
f.write("<head>")
f.write("<meta http-equiv=Refresh content=%d>\n" % 10)
f.write("</head>")
f.write('<body BGCOLOR="#FFFFFF" LINK="#008000" VLINK="#008000" BACKGROUND="/~andreas/images/tile.marble.gif">')
f.write("<H2>Heartbeat status at %s</H2>" % time.strftime("%H:%M:%S", time.localtime(now)))
f.write("<table>")
f.write("<tr><th>Host</th><th>State</th><th>IP Addr</th><th>Res</th><th>Last change</th></tr>\n" )
for h in hosts:
f.write("<tr><td>%-24s</td><td>%-7s</td><td>%-16s</td><td>%-3s</td><td>%-17s</td></tr>\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("</table>")
f.write("<P>")
for m in msgs[len(msgs)-30:]:
f.write("%s<BR>" % 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(): def initcurses():
@@ -312,12 +343,79 @@ def exitcurses():
curses.nocbreak(); stdscr.keypad(0); curses.echo() curses.nocbreak(); stdscr.keypad(0); curses.echo()
curses.endwin() 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('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">')
res.append('<html><head>')
res.append('<title>%s %s</title>' % (code, cause))
res.append('</head><body>')
res.append('<h1>%s</h1>' % (cause))
res.append('<p>The requested URL %s was not found on this server.</p>' % uri)
res.append('<hr>')
res.append('<address>WatchArnsberg (Unix) Server at somewhere.planix.com Port %d</address>' % TPORT)
res.append('</body></html>')
else:
res.append('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">')
res.append("<html>")
res.append("<head>")
res.append("<meta http-equiv=Refresh content=%d>\n" % 60)
res.append("</head>")
res.append('<body BGCOLOR="#FFFFFF" LINK="#008000" VLINK="#008000" BACKGROUND="/~andreas/images/tile.marble.gif">')
res.append("<H2>Heartbeat status at %s</H2>" % time.strftime("%H:%M:%S", time.localtime(now)))
res.append("<table>")
res.append("<tr><th>Host</th><th>State</th><th>IP Addr</th><th>Res</th><th>Last change</th></tr>\n" )
for h in hosts:
res.append("<tr><td>%-24s</td><td>%-7s</td><td>%-16s</td><td>%-3s</td><td>%-17s</td></tr>\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("</table>")
res.append("<P>")
for m in msgs[len(msgs)-30:]:
res.append("%s<BR>" % 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 # Main
# #
initlog() initlog()
now=time.time() now=time.time()
@@ -336,9 +434,11 @@ ilist=[]
sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("",PORT)) sock.bind(("",PORT))
ilist.append(sock) ilist.append(sock)
serv=SocketServer.TCPServer((THOST,TPORT),HtmlHandler)
ilist.append(serv.fileno())
next=int(now)+1 next=int(now)+1
sleep=next - now sleep=next - now
while 1: while 1:
@@ -358,7 +458,9 @@ while 1:
sys.exit(0) sys.exit(0)
except select.error, value: except select.error, value:
if value[0] != 4: # interrupted system call if value[0] != 4: # interrupted system call
raise os.error, value print select.error, value
#raise os.error, value
continue
if visual: if visual:
exitcurses() exitcurses()
initcurses() initcurses()
@@ -367,18 +469,23 @@ while 1:
for fh in sr[0]: for fh in sr[0]:
if fh == sock: if fh == sock:
readsock() readsock()
if fh == serv.fileno():
serv.handle_request()
if now >= next: if now >= next:
next+=1 next=now+1
if int(now) % INTERVAL == startsec: if int(now) % INTERVAL == startsec:
dominute() updatestats()
## if int(now) % 60 == 0:
## genhtml(now)
checkoverdue()
if visual: if visual:
# stdscr.addstr(1 , 0, "Now is %s, Next is %s" % (now, next)) stdscr.move(1 , 0)
if DEBUG: stdscr.clrtoeol()
stdscr.addstr(1 , 0, "len(htab) is %s, Next is %s" % (len(htab), next)) displaytime()
else:
stdscr.move(1 , 0)
stdscr.clrtoeol()
displaytime()
sleep=next-now 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)) if DEBUG: sys.stderr.write("sleep=%s next=%s\n" % (sleep, next))