Skip to content

Instantly share code, notes, and snippets.

@urbans
Created April 12, 2012 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save urbans/2370936 to your computer and use it in GitHub Desktop.
Save urbans/2370936 to your computer and use it in GitHub Desktop.
Server supervisor on GAE
application: ****your app name****
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: main.py
import cgi
import datetime
import urllib
import wsgiref.handlers
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from datetime import datetime
######################################### functions ###########################################
def xstr(s):
"""NUll stringifying function"""
if s is None:
return ''
return str(s).encode("iso-8859-15", "xmlcharrefreplace")
def pretty_date(time=False):
"""
Get a datetime object or a int() Epoch timestamp and return a
pretty string like 'an hour ago', 'Yesterday', '3 months ago',
'just now', etc
"""
now = datetime.now()
if type(time) is int:
diff = now - datetime.fromtimestamp(time)
elif isinstance(time,datetime):
diff = now - time
elif not time:
diff = now - now
second_diff = diff.seconds
day_diff = diff.days
if day_diff < 0:
return ''
if day_diff == 0:
if second_diff < 10:
return "just now"
if second_diff < 60:
return str(second_diff) + " sec ago"
if second_diff < 120:
return "min ago"
if second_diff < 3600:
return str( second_diff / 60 ) + " mins ago"
if second_diff < 7200:
return "hour ago"
if second_diff < 86400:
return str( second_diff / 3600 ) + " hrs ago"
if day_diff == 1:
return "Yesterday"
if day_diff < 7:
return str(day_diff) + " days ago"
if day_diff < 31:
return str(day_diff/7) + " weeks ago"
if day_diff < 365:
return str(day_diff/30) + " months ago"
return str(day_diff/365) + " years ago"
def dfColorizer(s):
"""colorizes df output"""
elements = s.split()
outarr = []
color="#000"
hasDfPercent = None
for el in elements:
if el == None:
pass
elif el.find("%") != -1:
percent = float(el.split("%")[0])
hasDfPercent = percent
if percent > 95:
color="FF0000"
elif percent > 90:
color="FF6600"
elif percent > 70:
color="996600"
else:
color="006600"
outarr.append("<span style='font-size:1.7em;font-weight:bold;'><br>%s<br></span>" % (el))
else:
outarr.append("<span style='font-size:0.9em'>" + el + "</span>")
out = ("<font color='#%s'>%s</font>") % (color," ".join(outarr))
if hasDfPercent >= 0 and hasDfPercent <=100:
out = out + "<br>"
out = out + "<img src='http://chart.apis.google.com/chart?chbh=a,0&chs=150x20&cht=bhs&chco=%s,ffffff&chd=t:%s|100&chf=bg,s,00000000'>" % (color,percent)
return out
def timeToColor(time=False):
"""color for _last seen_ time"""
now = datetime.now()
if type(time) is int:
diff = now - datetime.fromtimestamp(time)
elif isinstance(time,datetime):
diff = now - time
elif not time:
diff = now - now
second_diff = diff.seconds
day_diff = diff.days
if day_diff < 0:
return ''
if day_diff == 0:
if second_diff < 600:
return "#00ca00"
if second_diff < 3600:
return "#006600"
if second_diff < 7200:
return "#bd7400"
if second_diff < 86400:
return "#ff0000"
if day_diff == 1:
return "#ff0000"
if day_diff < 7:
return "#ff0000"
if day_diff < 31:
return "#000"
#if day_diff < 365:
# return str(day_diff/30) + " months ago"
return "#000"
######################################### model ###########################################
class Status(db.Model):
"""Models an individual Guestbook entry with an author, content, and date."""
reportdate = db.DateTimeProperty(auto_now_add=True)
servername = db.StringProperty()
uptime = db.StringProperty(indexed=False)
freesysdisk = db.StringProperty(multiline=True,indexed=False)
freedatadisk1 = db.StringProperty(multiline=True,indexed=False)
freedatadisk2 = db.StringProperty(multiline=True,indexed=False)
pyserverdate = db.DateTimeProperty(indexed=False)
serverdate = db.StringProperty(indexed=False)
freemem = db.StringProperty(multiline=True, indexed=False)
apache = db.StringProperty(indexed=False)
php = db.StringProperty(indexed=False)
mysql = db.StringProperty(indexed=False)
load = db.StringProperty(indexed=False)
fullreport = db.TextProperty(indexed=False)
class UniqueServer(db.Model):
servername = db.StringProperty()
######################################### Index ###########################################
class Index(webapp.RequestHandler):
def get(self):
self.response.out.write('Coming soon')
######################################### Showing status ###########################################
class ListStatuses(webapp.RequestHandler):
def get(self):
self.response.out.write("<html><head>"
"<style>body{font-family:arial,helvetica;background-color:#444;}"
"th{color:#bbb;background-color:black;}"
"td{background-color:#ccc;}"
"h1{color:#ccc;}"
"</style>"
"</head>"
"<body>"
"<h1>Dashboard</h1><br />");
self.response.out.write("<table border=1 cellspacing=0 cellpadding=4><tr>"
"<th>Name</th>"
"<th>Last seen</th>"
"<th>Sys disk</th>"
"<th>Data disk 1</th>"
"<th>Data disk 2</th>"
"<th>Uptime</th>"
"<th>Time lag</th>"
"<th>Load</th>"
"<th>Free mem</th>"
"<th>Apache</th>"
"<th>PHP</th>"
"<th>MySql</th>"
"<th>Full report</th>"
"</tr>");
#find all servers ======================================
servers = db.GqlQuery("SELECT * FROM UniqueServer ORDER BY servername ASC")
for server in servers:
#find last status =====================================
statuses = db.GqlQuery("SELECT * FROM Status WHERE servername = '%s'"
"ORDER BY reportdate DESC LIMIT 1" % server.servername)
for s in statuses:
#get delta t =======================================
if s.pyserverdate == None or s.reportdate == None:
lag = "-"
else:
t1 = s.pyserverdate
t2 = s.reportdate
if t1 > t2:
delta = -(t1-t2).seconds
else:
delta = (t2-t1).seconds
lag = str(delta) + " s"
#print table row ===================================
self.response.out.write("<tr>"
"<td style='background-color:%s;'>%s&nbsp;</td>" #name
"<td title='%s' style='background-color:%s;'>%s&nbsp;</td>" #last seen
"<td>%s&nbsp;</td>" #free sys disk
"<td>%s&nbsp;</td>" #free data disk1
"<td>%s&nbsp;</td>" #free data disk2
"<td>%s&nbsp;</td>" #uptime
"<td title='%s'>%s&nbsp;</td>" #system date lag
"<td>%s&nbsp;</td>" #load
"<td>%s&nbsp;</td>" #free mem
"<td>%s&nbsp;</td>" #apache
"<td>%s&nbsp;</td>" #PHP
"<td>%s&nbsp;</td>" #Mysql
"<td title='%s'>...</td>" #Full report
"</tr>" % (
timeToColor(s.reportdate), xstr(s.servername),
xstr(s.reportdate), timeToColor(s.reportdate) ,pretty_date(s.reportdate),
dfColorizer(xstr(s.freesysdisk)),
dfColorizer(xstr(s.freedatadisk1)),
dfColorizer(xstr(s.freedatadisk2)),
xstr(s.uptime),
xstr(s.serverdate),
xstr(lag),
xstr(s.load),
xstr(s.freemem),
xstr(s.apache),
xstr(s.php),
xstr(s.mysql),
xstr(s.fullreport).replace("'",'"'))
);
#close table =============================================
self.response.out.write('</table></body></html>');
######################################### POSTING DATA ###########################################
class PostStatus(webapp.RequestHandler):
"""Handle incoming requests and save to database"""
def post(self):
#get and validate server name ==================
cursrvname = self.request.get('servername')
if cursrvname == None:
return
#store server to table of servers ==============
result = db.GqlQuery("SELECT * FROM UniqueServer WHERE servername = '%s'" % cursrvname)
if result.count() == 0:
newsrv = UniqueServer()
newsrv.servername = cursrvname
newsrv.put()
#store status ==================================
s = Status()
s.servername = cursrvname
s.freesysdisk = self.request.get('freesysdisk') or None
s.freedatadisk1 = self.request.get('freedatadisk1') or None
s.freedatadisk2 = self.request.get('freedatadisk2') or None
s.uptime = self.request.get('uptime') or None
s.serverdate = self.request.get('serverdate') or None
s.freemem = self.request.get('freemem') or None
s.apache = self.request.get('apache') or None
s.php = self.request.get('php') or None
s.mysql = self.request.get('mysql') or None
s.load = self.request.get('load') or None
s.fullreport = self.request.get('fullreport') or None
if self.request.get('pyserverdate'):
s.pyserverdate = datetime.strptime(self.request.get('pyserverdate'),"%Y-%m-%d %H:%M:%S")
s.put()
self.response.out.write('ok')
def get(self):
self.post()
######################################### Housekeeping ###########################################
application = webapp.WSGIApplication([
('/', Index),
('/showstatus', ListStatuses),
('/post', PostStatus)
], debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment