X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=www%2Fprintbadnodes.py;h=47ef62e49a49c20885937852f56ff5d6548b4518;hb=refs%2Fheads%2F1.0;hp=c8bbfcb4d670ea958208f6213534f632349da7fc;hpb=ba6cc9b30b0741e10033a769202047ddeb96f6d1;p=monitor.git
diff --git a/www/printbadnodes.py b/www/printbadnodes.py
index c8bbfcb..47ef62e 100755
--- a/www/printbadnodes.py
+++ b/www/printbadnodes.py
@@ -1,13 +1,13 @@
#!/usr/bin/python
-import soltesz
-from config import config
-from optparse import OptionParser
+from monitor import database
+from monitor import config
import string
-
import sys
+import time
categories = {}
ssherror = False
+fb = {}
def sec2days(sec):
if sec == "null":
@@ -63,11 +63,11 @@ def cmpState(l1, l2):
return cmpMap(l1,l2,'state', map)
def cmpCategoryVal(v1, v2):
- map = array_to_priority_map([ None, 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'ERROR', ])
+ map = array_to_priority_map([ None, 'ALPHA', 'PROD', 'OLDPROD', 'OLDBOOTCD', 'UNKNOWN', 'FORCED', 'ERROR', ])
return cmpValMap(v1,v2,map)
def cmpCategory(l1, l2):
- map = array_to_priority_map([ 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'ERROR', ])
+ map = array_to_priority_map([ 'ALPHA', 'PROD', 'OLDPROD', 'OLDBOOTCD', 'UNKNOWN', 'ERROR', ])
return cmpMap(l1,l2,'category', map)
def cmpPCU(l1, l2):
@@ -144,9 +144,32 @@ def ssh_error_to_str(str):
return ssh_error
+def pcu_state(pcu_id):
+ global fb
+
+ if 'nodes' in fb and "id_%s" % pcu_id in fb['nodes'] \
+ and 'values' in fb['nodes']["id_%s" % pcu_id]:
+ rec = fb['nodes']["id_%s" % pcu_id]['values']
+ if 'reboot' in rec:
+ rb = rec['reboot']
+ if rb == 0 or rb == "0":
+ return 0
+ elif "NetDown" == rb or "Not_Run" == rb:
+ return 1
+ else:
+ return -1
+ else:
+ return -1
+ else:
+ return -1
+
def fields_to_html(fields, vals):
global categories
global ssherror
+ pcu_colorMap = { -1 : 'indianred',
+ 0 : 'darkseagreen',
+ 1 : 'gold', }
+
colorMap = { 'PING' : 'darkseagreen',
'NOPING': 'darksalmon',
'SSH': 'darkseagreen',
@@ -199,7 +222,11 @@ def fields_to_html(fields, vals):
r_str += "
%s | " % (bgcolor, f)
elif f == 'PCU':
if len(vals['plcnode']['pcu_ids']) > 0:
- url = "PCU" % vals['plcnode']['pcu_ids'][0]
+ #print "pcu_id: %s
" % vals['plcnode']['pcu_ids'][0]
+ #print "state: %s
" % pcu_state(vals['plcnode']['pcu_ids'][0])
+ #print "color: %s
" % pcu_colorMap[pcu_state(vals['plcnode']['pcu_ids'][0])]
+ bgcolor = "bgcolor='%s'" % pcu_colorMap[pcu_state(vals['plcnode']['pcu_ids'][0])]
+ url = "PCU" % vals['plcnode']['pcu_ids'][0]
r_str += "%s | " % (bgcolor, url)
else:
r_str += "%s | " % (bgcolor, f)
@@ -208,10 +235,59 @@ def fields_to_html(fields, vals):
return r_str
+def my_diff_time(timestamp):
+ now = time.time()
+ if timestamp == None:
+ return "not yet contacted"
+ diff = now - timestamp
+ # return the number of seconds as a difference from current time.
+ t_str = ""
+ if diff < 60: # sec in min.
+ t = diff
+ t_str = "%s sec ago" % t
+ elif diff < 60*60: # sec in hour
+ t = diff // (60)
+ t_str = "%s min ago" % int(t)
+ elif diff < 60*60*24: # sec in day
+ t = diff // (60*60)
+ t_str = "%s hours ago" % int(t)
+ elif diff < 60*60*24*7: # sec in week
+ t = diff // (60*60*24)
+ t_str = "%s days ago" % int(t)
+ elif diff < 60*60*24*30: # approx sec in month
+ t = diff // (60*60*24*7)
+ t_str = "%s weeks ago" % int(t)
+ elif diff > 60*60*24*30 and diff < 60*60*24*30*2: # approx sec in month
+ month = int( diff // (60*60*24*30) )
+ weeks = (diff - (month * (60*60*24*30))) // (60*60*24*7)
+ if weeks == 0:
+ t_str = "%s month ago" % int(month)
+ elif weeks == 4:
+ t_str = "2 months ago"
+ else:
+ t_str = "%s month and %s weeks ago" % ( int(month) , int(weeks) )
+ elif diff >= 60*60*24*30*2:
+ month = diff // (60*60*24*30)
+ t_str = "%s months ago" % int(month)
+ return t_str
+
+
+def main(sitefilter, catfilter, statefilter, comonfilter, nodeonlyfilter):
+ global fb
+ import os
+ import datetime
+ if nodeonlyfilter == None:
+ print "\n"
+
+ try:
+ mtime = os.stat("/var/lib/monitor-server/production.findbad.pkl")[-2]
+ print "Last Updated: %s GMT" % datetime.datetime.fromtimestamp(mtime)
+ except:
+ pass
-def main(sitefilter):
- db = soltesz.dbLoad(config.dbname)
+ db = database.dbLoad(config.dbname)
+ fb = database.dbLoad("findbadpcus")
## Field widths used for printing
maxFieldLengths = { 'nodename' : -45,
@@ -222,6 +298,7 @@ def main(sitefilter):
'state' : 5,
'kernel' : 10.65,
'comonstats' : 5,
+ 'last_contact' : 10.65,
'plcsite' : 12,
'bootcd' : 10.65}
## create format string based on config.fields
@@ -230,6 +307,7 @@ def main(sitefilter):
format_fields = []
for f in config.fields.split(','):
fields[f] = "%%(%s)s" % f
+ #print f
#if f in maxFieldLengths:
# fields[f] = "%%(%s)%ds" % (f, maxFieldLengths[f])
#else:
@@ -258,6 +336,11 @@ def main(sitefilter):
# d2 was an array of [{node}, {}, ...]
# the bysite is a loginbase dict of [{node}, {node}]
d2 = []
+ import re
+ if sitefilter != None:
+ sf = re.compile(sitefilter)
+ else:
+ sf = None
for nodename in l_nodes:
vals=d_n[nodename]['values']
v = {}
@@ -267,7 +350,7 @@ def main(sitefilter):
'status' in vals['plcsite'] and \
vals['plcsite']['status'] == "SUCCESS":
- url = "%s" % ( vals['plcsite']['login_base'],
+ url = "%s" % ( vals['plcsite']['login_base'],
vals['plcsite']['login_base'])
site_string = "%s %2s nodes :: %2s of %4s slices" % ( \
@@ -283,7 +366,7 @@ def main(sitefilter):
v['site_string'] = site_string
v['loginbase'] = loginbase
- if (sitefilter != None and loginbase == sitefilter) or sitefilter == None:
+ if (sitefilter != None and sf.match(loginbase) != None) or sitefilter == None:
d2.append(v)
@@ -313,23 +396,52 @@ def main(sitefilter):
d2.sort(cmp=cmpCategory)
+ if catfilter != None: cf = re.compile(catfilter)
+ else: cf = None
+
+ if statefilter != None: stf = re.compile(statefilter)
+ else: stf = None
+
+ if comonfilter != None: cmf = re.compile(comonfilter)
+ else: cmf = None
+
+
+ output_str = ""
#l_loginbase = bysite.keys()
#l_loginbase.sort()
- print ""
+ if nodeonlyfilter == None:
+ output_str += ""
+
prev_sitestring = ""
for row in d2:
+ vals = row
+
+ #added by guto about last contact information
+ if (catfilter != None and cf.match(vals['category']) == None):
+ continue
+
+ if (statefilter != None and stf.match(vals['state']) == None):
+ continue
+
+ if (comonfilter != None and comonfilter in vals['comonstats'] and vals['comonstats'][comonfilter] != 'null'):
+ continue
+
+ if nodeonlyfilter != None:
+ output_str += vals['nodename']
+ continue
+
site_string = row['site_string']
if site_string != prev_sitestring:
- print ""
- print site_string
- print " | "
+ output_str += "
"
+ output_str += site_string
+ output_str += " | "
else:
- print "
| "
+ output_str += "
| "
prev_sitestring = site_string
- vals = row
+
# convert uname values into a single kernel version string
if 'kernel' in vals:
kernel = vals['kernel'].split()
@@ -367,6 +479,16 @@ def main(sitefilter):
vals['reboot'] = "%s" % vals['reboot']
vals['reboot'] = vals['reboot'].replace(" ", "_")
+ if 'nodename' in vals:
+ url = "%s" % (config.MONITOR_HOSTNAME, vals['nodename'], vals['nodename'])
+ vals['nodename'] = url
+
+ if 'plcnode' in vals:
+ if vals['plcnode']['status'] == "GN_FAILED":
+ vals['last_contact'] = "UNKNOWN"
+ else:
+ vals['last_contact'] = my_diff_time(vals['plcnode']['last_contact'])
+
try:
str_fields = []
count = 0
@@ -377,64 +499,75 @@ def main(sitefilter):
print >>sys.stderr, vals
s = fields_to_html(str_fields, vals)
- print s
+ output_str += s
- print "\n
"
+ output_str += "\n"
- print "
"
- print ""
+ if nodeonlyfilter == None:
+ output_str += "
"
keys = categories.keys()
keys.sort()
+ print ""
for cat in keys:
print ""
print "Total %s | " % cat
print "%s | " % categories[cat]
print "
"
- print "
"
+ if nodeonlyfilter == None:
+ print "
"
+
+ print output_str
+ if nodeonlyfilter == None:
+ print "\n"
+
-import cgi
-import cgitb;
-cgitb.enable()
-import sys
-form = cgi.FieldStorage()
-myfilter = None
+if __name__ == '__main__':
+ import cgi
+ import cgitb;
+ cgitb.enable()
+ import sys
-if form.has_key('site'):
- myfilter = form.getvalue("site")
-else:
+ form = cgi.FieldStorage()
myfilter = None
+ if form.has_key('site'):
+ myfilter = form.getvalue("site")
+ else:
+ myfilter = None
+
+ if form.has_key('category'):
+ mycategory = form.getvalue("category")
+ else:
+ mycategory = None
+
+ if form.has_key('state'):
+ mystate = form.getvalue("state")
+ else:
+ mystate = None
+
+ if form.has_key('comon'):
+ mycomon = form.getvalue("comon")
+ else:
+ mycomon = None
+
+ if form.has_key('nodeonly'):
+ mynodeonly = form.getvalue("nodeonly")
+ else:
+ mynodeonly = None
+
+ config.cmpdays=False
+ config.comon="sshstatus"
+ config.fields="nodename,ping,ssh,pcu,category,state,last_contact,kernel,bootcd"
+ config.dbname="findbad"
+ config.cmpping=False
+ config.cmpdns=False
+ config.cmploginbase=False
+ config.cmpssh=False
+ config.cmpcategory=False
-if __name__ == '__main__':
- parser = OptionParser()
- parser.set_defaults(cmpdays=False,
- comon="sshstatus",
- fields="nodename,ping,ssh,pcu,category,state,kernel,bootcd",
- dbname="findbad", # -070724-1",
- cmpping=False,
- cmpdns=False,
- cmploginbase=False,
- cmpssh=False,
- cmpcategory=False,
- cmpstate=False)
- parser.add_option("", "--fields", dest="fields", help="")
- parser.add_option("", "--dbname", dest="dbname", help="")
- parser.add_option("", "--days", dest="cmpdays", action="store_true", help="")
- parser.add_option("", "--ping", dest="cmpping", action="store_true", help="")
- parser.add_option("", "--dns", dest="cmpdns", action="store_true", help="")
- parser.add_option("", "--ssh", dest="cmpssh", action="store_true", help="")
- parser.add_option("", "--loginbase",dest="cmploginbase",action="store_true", help="")
- parser.add_option("", "--category", dest="cmpcategory", action="store_true", help="")
- parser.add_option("", "--kernel", dest="cmpkernel", action="store_true", help="")
- parser.add_option("", "--state", dest="cmpstate", action="store_true", help="")
- parser.add_option("", "--comon", dest="comon", help="")
- config = config(parser)
- config.parse_args()
print "Content-Type: text/html\r\n"
- print "\n"
if len(sys.argv) > 1:
if sys.argv[1] == "ssherror":
ssherror = True
- main(myfilter)
- print "\n"
+ main(myfilter, mycategory, mystate, mycomon,mynodeonly)