00001
00002 '''
00003 This Module is the start module for the display tool.
00004
00005 Reading University
00006 MSc in Network Centred Computing
00007 a.weise - a.weise@reading.ac.uk - December 2005
00008 '''
00009 import gui_classes
00010 import os, getopt, sys, re, time
00011
00012
00013 import sqlite
00014
00015
00016 from gui_utils import usage_exit, check_date, convert_date, check_ip, find_item, help_context, check_time, LoadConfig
00017
00018 class Display:
00019 '''
00020 This is main class for the gui application.
00021 '''
00022
00023 def __init__(self, config):
00024 '''
00025 Constructor
00026 '''
00027 workingpath = os.getcwd()
00028
00029 self._database_name = config.get("database.name")
00030 self._database_path = config.get("database.path")
00031 self._database_path = self._database_path.rstrip("/")
00032 if(config.get("database.path") == '' or config.get("database.path") == None):
00033
00034 self._database_path = workingpath
00035
00036 else:
00037 self._database_name = self._database_name.strip()
00038 if (-1 != self._database_path.find("/", 0, 1)):
00039
00040 pass
00041 else:
00042 self._database_path = workingpath+"/"+self._database_path
00043
00044 if(0 == os.access((self._database_path+"/"+self._database_name), 4)):
00045 print "\nCould not access database under \"%s\" !\nMaybe change configuration file and try again!\n\n" % (self._database_path+"/"+self._database_name)
00046 os._exit(-1)
00047
00048 def execute_sql(self, wait, database_obj, sql, col):
00049 '''
00050 This function tries to get access to a database for "wait" seconds. Either the sql query gets executed or the if no acccess is possible the program exits.
00051 '''
00052
00053 for i in range(0, wait):
00054 try:
00055 database_obj.execute(sql)
00056 data = database_obj.fetchall()
00057 return data
00058 except sqlite.OperationalError:
00059 if i%10 == 0:
00060 text = "database temporary locked - keep trying for another %d seconds ...." % (wait-i)
00061 if col == 1:
00062 col_obj = gui_classes.Colour()
00063 text = col_obj.yellow(text)
00064 print text
00065 time.sleep(1)
00066
00067 text = "Database busy, could not apply request. Please try again."
00068 if col == 1:
00069 text = col_obj.yellow(text)
00070
00071 print text,"\n\n"
00072 os._exit(0)
00073
00074 def sql_host(self, col):
00075 '''
00076 This function gets all hosts from the database.
00077 '''
00078 sql = ' SELECT * FROM host, host_project, project'\
00079 ' WHERE host.h_id = host_project.hp_h_id '\
00080 ' AND host_project.hp_p_id = project.p_id'
00081
00082 database = self._database_path+"/"+self._database_name
00083
00084 connect = sqlite.connect(database, autocommit = 1)
00085 db_access = connect.cursor()
00086 data = self.execute_sql(120, db_access, sql, col)
00087 return data
00088
00089
00090 def sql_project(self, col):
00091 '''
00092 This function gets all projects from the database
00093 '''
00094 sql = ' SELECT * FROM project '
00095 database = self._database_path+"/"+self._database_name
00096 connect = sqlite.connect(database, autocommit = 1)
00097 db_access = connect.cursor()
00098 data = self.execute_sql(120, db_access, sql, col)
00099 return data
00100
00101
00102 def sql_error(self, col, d1 = None, d2 = None, t1 = None, t2 = None, host = None, project = None, error = None):
00103 '''
00104 This function gets all error messages from the database.
00105 '''
00106 where = 0
00107 sql = ' SELECT * FROM error, messages, host, host_project, project '
00108
00109 if d1 != None and d2 != None:
00110
00111 sql += ' WHERE '
00112 where = 1
00113 sql += ' messages.m_date BETWEEN "%s" AND "%s" ' % (d1, d2)
00114
00115 elif d1 != None and d2 == None:
00116
00117 sql += ' WHERE '
00118 where = 1
00119 now = time.strftime("%Y-%m-%d", time.localtime())
00120 sql += ' messages.m_date BETWEEN "%s" AND "%s" ' % (d1, now)
00121
00122 elif d1 == None and d2 != None:
00123
00124 sql += ' WHERE '
00125 where = 1
00126 start_ = "1970-01-01"
00127 sql += ' messages.m_date BETWEEN "%s" AND "%s" ' % (start_, d2)
00128
00129 else:
00130 pass
00131
00132 if where == 0:
00133 sql += ' WHERE '
00134 where = 1
00135 else:
00136 sql += ' AND '
00137
00138 if t1 != None and t2 != None:
00139
00140 sql += ' messages.m_time BETWEEN "%s" AND "%s" ' % (t1, t2)
00141 sql += ' AND '
00142
00143 elif t1 != None and t2 == None:
00144
00145 now = time.strftime("%H:%M:%S", time.localtime())
00146 sql += ' messages.m_time BETWEEN "%s" AND "%s" ' % (t1, now)
00147 sql += ' AND '
00148
00149 elif t1 == None and t2 != None:
00150
00151 start_ = "00:00:00"
00152 sql += ' messages.m_time BETWEEN "%s" AND "%s" ' % (start_, t2)
00153 sql += ' AND '
00154
00155 sql += ' messages.error_e_id = error.e_id '
00156
00157 if error != None:
00158 sql += ' AND ( '
00159 for i in range(len(error)):
00160 sql += ' error.e_number = \"%s\" ' % error[i]
00161 if len(error) > (i+1):
00162 sql += ' OR '
00163 sql += ' ) '
00164
00165 if host != None:
00166 sql += ' AND messages.host_h_id = host.h_id AND host.h_ip_address = "%s" ' % host
00167 elif host == None:
00168 sql += ' AND messages.host_h_id = host.h_id '
00169
00170 sql += ' AND host.h_id = host_project.hp_h_id '\
00171 ' AND host_project.hp_p_id = project.p_id '
00172
00173 if project != None:
00174 sql += ' AND project.p_name = "%s" ' % project
00175
00176
00177 sql += 'ORDER BY messages.m_date, messages.m_time'
00178
00179 database = self._database_path+"/"+self._database_name
00180 connect = sqlite.connect(database, autocommit = 1)
00181 db_access = connect.cursor()
00182 data = self.execute_sql(120, db_access, sql, col)
00183 return data
00184
00185 def display_graph(self, dataset, col, file_fd = None):
00186 '''
00187 This function displays a barchart diagram containing Error Numbers and the corresponding Frequency
00188 '''
00189 field = []
00190 field_label = []
00191 table_error = []
00192 for i in range(len(dataset)):
00193
00194 index = find_item(int(dataset[i]['error.e_number']), field)
00195 if (None == index):
00196 field.append([int(dataset[i]['error.e_number']), 1])
00197 field_label.append([int(dataset[i]['error.e_number']), 1])
00198 table_error.append( [int(dataset[i]['error.e_number']), 1, dataset[i]['error.e_name']])
00199 else:
00200 count = field[index][1]
00201 count += 1
00202 field[index][1] = count
00203 field_label[index][1] = count
00204 table_error[index][1] = count
00205
00206 field.sort()
00207 field_label.sort()
00208 table_error.sort()
00209
00210 h_line = "-------------------------------------------------------------------------"
00211 v_line = "|"
00212 header = "\nFrequency of Errors: \n"
00213
00214 if file_fd != None:
00215 content = header
00216 content += "\n\n Nr. | Error Number\t| Frequency\t| Error Name\t\t\t\n\n"
00217 file_fd.write(content)
00218
00219 if col == 1:
00220 col_obj = gui_classes.Colour()
00221 header = col_obj.yellow(header)
00222 h_line = col_obj.yellow(h_line)
00223 v_line = col_obj.yellow(v_line)
00224
00225 print header
00226 print h_line
00227 print " Nr. "+v_line+" Error Number\t"+v_line+" Frequency\t"+v_line+" Error Name\t\t\t"
00228 print h_line
00229
00230 for i in range(len(table_error)):
00231 print " %5d %s %7s\t%s %6s\t%s %s" % ((i+1), v_line, table_error[i][0], v_line, table_error[i][1], v_line, table_error[i][2])
00232
00233 if file_fd != None:
00234 content = " %5d | %7s\t| %6s\t| %s\n" % ((i+1), table_error[i][0], table_error[i][1], table_error[i][2])
00235 file_fd.write(content)
00236
00237 print h_line
00238
00239 for i in range(len(field)):
00240 field_label[i][0] = (i+1)
00241 field_label[i][1] = "%d" % field[i][0]
00242 field[i][0] = (i+1)
00243
00244 window = []
00245
00246 pic_obj = gui_classes.Picture(col, window)
00247 pic_obj.show_barchart("Diagram \"Error Number - Frequency\"", field, field_label, "ERROR NUMBER", "FREQUENCY", dataset, select_type = "error", filus_fd = file_fd, descript = "Diagram \"Error Number - Frequency\"")
00248 pic_obj.mainloop()
00249
00250
00251
00252 def start():
00253
00254 '''
00255 Start the application.
00256 '''
00257 verbose = 0
00258 col = 1
00259 graph = 0
00260 filus = None
00261 configfile = ""
00262 sql_host = None
00263 sql_project = None
00264 sql_error = None
00265 sql_error_freq = None
00266 date1 = None
00267 date2 = None
00268 time1 = None
00269 time2 = None
00270 ip = None
00271 port = None
00272 project = None
00273 error = None
00274
00275
00276 try:
00277 opts, args = getopt.getopt(sys.argv[1:], 'c:vhg', ['config=', 'verbose', 'graph', 'nocolor', 'help', 'sql_host', 'sql_project', 'sql_error', 'sql_error_freq', 'start_date=', 'end_date=', 'start_time=', 'end_time=', 'ip=', 'port=', 'project=', 'error=' , 'file='])
00278 for opt, value in opts:
00279 if opt in ('', '--nocolor'):
00280 col = 0
00281 if opt in ('-h','--help'):
00282 msg = help_context(col)
00283 usage_exit(sys.argv[0], msg, col)
00284 if opt in ('-c', '--config'):
00285 value = value.replace("=", "")
00286 configfile = os.getcwd()+"/"+value
00287 if opt in ('-v', '--verbose'):
00288 verbose = 1
00289 if opt in ('-g', '--graph'):
00290 graph = 1
00291
00292 for opt, value in opts:
00293 if opt in ('', '--sql_host'):
00294 sql_host = 1
00295 if opt in ('', '--sql_project'):
00296 sql_project = 1
00297 if opt in ('', '--sql_error'):
00298 sql_error = 1
00299 if opt in ('', '--sql_error_freq'):
00300 sql_error_freq = 1
00301 if opt in ('', '--error'):
00302 error = value
00303 error = error.strip()
00304 error = error.strip(",")
00305 error = error.split(",")
00306 for i in range(len(error)):
00307 error[i] = error[i].strip()
00308 try:
00309 error[i] = int(error[i])
00310 except ValueError, e:
00311
00312 usage_exit(sys.argv[0], 'invalid literal for int()' , col)
00313 if opt in ('', '--start_date'):
00314 date1 = value
00315 status = re.search('^[0-3][0-9].[0-1][0-9].[1-9][0-9]{3}', date1)
00316 if (None == status):
00317 usage_exit(sys.argv[0], 'given date is not valid', col)
00318 else:
00319 date1 = status.string[status.start():status.end()]
00320 if (0 == check_date(date1)):
00321 date1 = convert_date(date1)
00322 else:
00323 usage_exit(sys.argv[0], 'given date is not valid', col)
00324 if opt in ('','--end_date'):
00325 date2 = value
00326 status = re.search('^[0-3][0-9].[0-1][0-9].[1-9][0-9]{3}', date2)
00327 if (None == status):
00328 usage_exit(sys.argv[0], 'given date is not valid', col)
00329 else:
00330 date2 = status.string[status.start():status.end()]
00331 if (0 == check_date(date2)):
00332 date2 = convert_date(date2)
00333 print "date 2: ", date2
00334 else:
00335 usage_exit(sys.argv[0], 'given date is not valid', col)
00336 if opt in ('', '--start_time'):
00337 time1 = value
00338 status = re.search('^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]', time1)
00339 if (None == status):
00340 usage_exit(sys.argv[0], 'given time is not valid', col)
00341 else:
00342 time1 = status.string[status.start():status.end()]
00343 if ( 0 == check_time(time1)):
00344 pass
00345 else:
00346 usage_exit(sys.argv[0], 'given time is not valid', col)
00347 if opt in ('', '--end_time'):
00348 time2 = value
00349 status = re.search('^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]', time2)
00350 if (None == status):
00351 usage_exit(sys.argv[0], 'given time is not valid', col)
00352 else:
00353 time2 = status.string[status.start():status.end()]
00354 if ( 0 == check_time(time2)):
00355 pass
00356 else:
00357 usage_exit(sys.argv[0], 'given time is not valid', col)
00358 if opt in ('','--ip'):
00359 ip = value
00360 status = re.search('^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}', ip)
00361 if (None == status):
00362 usage_exit(sys.argv[0], 'given IP is not valid', col)
00363 else:
00364 ip = status.string[status.start():status.end()]
00365 if (0 == check_ip(ip)):
00366 print "ip: ", ip
00367 else:
00368 usage_exit(sys.argv[0], 'given IP is not valid', col)
00369 if opt in ('', '--port'):
00370 port = int(value)
00371 if (port < 1024 or port > 50001):
00372 usage_exit(sys.argv[0], "Server port is out of range! \nMake sure the server port lies between 1025 (inclusive) and 50000 (inclusive)!\n\n", col)
00373 if opt in ('','--project'):
00374 project = value
00375 if opt in ('', '--file'):
00376 filus = value
00377 except getopt.error, e:
00378 e = "%s" % (e)
00379 usage_exit(sys.argv[0], e, col)
00380 except ValueError, e:
00381 e = "%s" % (e)
00382 usage_exit(sys.argv[0], e, col)
00383
00384
00385
00386 if (configfile != ""):
00387
00388 if(1 == os.path.exists(configfile)):
00389 config = LoadConfig(configfile)
00390 else:
00391
00392 print "\n\nSorry, a given config file does NOT exist !\nPlease try again!\n\n"
00393 os._exit(-1)
00394 else:
00395 msg = "\nNo config file spezified !\n"
00396 usage_exit(sys.argv[0], msg, col)
00397
00398 if col == 1:
00399 col_obj = gui_classes.Colour()
00400
00401 gui = Display(config)
00402
00403 if verbose == 1:
00404 i = 1
00405 d = config.iteritems()
00406 while(1):
00407 try:
00408 print i, ". ", d.next()
00409 i += 1
00410 except:
00411 break
00412
00413 if filus != None:
00414
00415
00416 try:
00417 filus_fd = file(filus, 'r')
00418 quest = "File \"%s\" already exists, overwrite file (y/n) ? -> " % filus
00419 if col == 1:
00420 quest = col_obj.darkred(quest)
00421 decision = raw_input(quest)
00422 if decision == 'y' or decision == 'Y' or decision == 'yes' or decision == 'Yes' or decision == 'YES':
00423 filus_fd.close()
00424 filus_fd = file(filus, 'w')
00425 else:
00426 os._exit(0)
00427 except IOError:
00428 filus_fd = file(filus, 'w')
00429
00430
00431
00432 if (1 == sql_host):
00433 print "sql_host: ", sql_host
00434 data = gui.sql_host(col)
00435
00436 if len(data) == 0:
00437 text = "\n\nSorry, no data available for you request!"
00438 if col == 1:
00439 text = col_obj.yellow(text)
00440 print text
00441 print "\n\n"
00442 os._exit(0)
00443
00444 h_line = "-----------------------------------------------------------------------------"
00445 v_line = "|"
00446
00447 if col == 1:
00448 h_line = col_obj.yellow(h_line)
00449 v_line = col_obj.yellow(v_line)
00450
00451
00452 print h_line
00453 print " Nr.\t"+v_line+"\tHost IP\t\t\t"+v_line+" Host Name "+v_line+" Project "
00454 print h_line
00455
00456
00457 for i in range(len(data)):
00458 print " %d\t%s\t%s\t\t%s %17s %s %s" % ((i+1), v_line, data[i]['host.h_ip_address'], v_line, data[i]['host.h_hostname'], v_line, data[i]['project.p_name'])
00459
00460 print h_line
00461
00462 elif (1 == sql_project):
00463 print "sql_project: ", sql_project
00464 data = gui.sql_project(col)
00465
00466 if len(data) == 0:
00467 text = "\n\nSorry, no data available for you request!"
00468 if col == 1:
00469 text = col_obj.yellow(text)
00470 print text
00471 print "\n\n"
00472 os._exit(0)
00473
00474 h_line = "-----------------------------------------"
00475 v_line = "|"
00476
00477 if col == 1:
00478 h_line = col_obj.yellow(h_line)
00479 v_line = col_obj.yellow(v_line)
00480
00481
00482 print h_line
00483 print v_line+" Nr.\t"+v_line+"\tProject\t\t\t"+v_line
00484 print h_line
00485
00486
00487 for i in range(len(data)):
00488 print "%s %d\t%s\t%s\t\t%s" % (v_line, (i+1), v_line, data[i]['p_name'], v_line)
00489
00490 print h_line
00491
00492
00493 elif (1 == sql_error):
00494
00495 data = gui.sql_error(col, d1=date1, d2=date2, t1 = time1, t2 = time2, host = ip, project = project, error = error)
00496
00497 if len(data) == 0:
00498 text = "\n\nSorry, no data available for you request!"
00499 if col == 1:
00500 text = col_obj.yellow(text)
00501 print text
00502 print "\n\n"
00503 os._exit(0)
00504
00505
00506 h_line = "------------------------------------------------------------------------------------------------------------------"
00507 v_line = "|"
00508 h_line_short = "-"
00509 header = " Nr. | Date | Time |\t\t\t\tError String"
00510 ln = "LN"
00511 en = "EN"
00512 ip = "IP"
00513 pr = "PR"
00514
00515 brown_line = h_line
00516 if col == 1:
00517 brown_line = col_obj.brown(h_line)
00518 h_line = col_obj.yellow(h_line)
00519 v_line = col_obj.yellow(v_line)
00520 h_line_short = col_obj.yellow(h_line_short)
00521 header = col_obj.yellow(header)
00522 ln = col_obj.yellow(ln)
00523 en = col_obj.yellow(en)
00524 ip = col_obj.yellow(ip)
00525 pr = col_obj.yellow(pr)
00526
00527 print h_line
00528
00529 print header
00530
00531 if filus != None:
00532 content = " Nr.\t| Date | Time | \t\t\t\tError String\t\t\t\t | Line Number | Error Number | Host IP | Project\n\n"
00533 filus_fd.write(content)
00534 print h_line
00535
00536
00537 for i in range(len(data)):
00538 print "%6d %s %10s %s %6s %s %70s" % ((i+1), v_line, data[i]['messages.m_date'], v_line, data[i]['messages.m_time'], v_line, data[i]['messages.m_error_string'])
00539 print "%s: %7s %s %s: %6s %s %s: %15s %s %s: %s" % (ln, data[i]['messages.m_line_number'], h_line_short, en, data[i]['error.e_number'], h_line_short, ip, data[i]['host.h_ip_address'], h_line_short, pr, data[i]['project.p_name'])
00540
00541
00542 if filus != None:
00543 content = " %d\t| %10s | %6s | %70s | %10s | %10s | %15s | %s \n" % ((i+1), data[i]['messages.m_date'], data[i]['messages.m_time'], data[i]['messages.m_error_string'], data[i]['messages.m_line_number'], data[i]['error.e_number'], data[i]['host.h_ip_address'], data[i]['project.p_name'])
00544 filus_fd.write(content)
00545 if len(data) > (i+1):
00546 print brown_line
00547
00548
00549 print h_line
00550
00551 print "\nAbbreviations:\n\n%s - Line Number in original SRB log file\n%s - Error Number\n%s - Host IP Address\n%s - Project\n\n" % (ln, en, ip, pr)
00552
00553 if graph == 1:
00554 if filus != None:
00555 gui.display_graph(data, col, file_fd = filus_fd)
00556 else:
00557 if filus != None:
00558 filus_fd.close()
00559 gui.display_graph(data, col)
00560
00561 elif ( 1 == sql_error_freq):
00562
00563 data = gui.sql_error(col, d1=date1, d2=date2, t1 = time1, t2 = time2, host = ip, project = project, error = error)
00564
00565 if len(data) == 0:
00566 text = "\n\nSorry, no data available for you request!"
00567 if col == 1:
00568 text = col_obj.yellow(text)
00569 print text
00570 print "\n\n"
00571 os._exit(0)
00572
00573
00574 print "datasets: ", len(data)
00575
00576 if graph == 0:
00577 field = []
00578 field_label = []
00579 table_error = []
00580 for i in range(len(data)):
00581 index = find_item(int(data[i]['error.e_number']), field)
00582 if (None == index):
00583 field.append([int(data[i]['error.e_number']), 1])
00584 field_label.append([int(data[i]['error.e_number']), 1])
00585 table_error.append( [int(data[i]['error.e_number']), 1, data[i]['error.e_name']])
00586
00587 else:
00588 count = field[index][1]
00589 count += 1
00590 field[index][1] = count
00591 field_label[index][1] = count
00592 table_error[index][1] = count
00593
00594 field.sort()
00595 field_label.sort()
00596 table_error.sort()
00597
00598 h_line = "-------------------------------------------------------------------------"
00599 v_line = "|"
00600 header = "\nFrequency of Errors: \n"
00601
00602 if col == 1:
00603 header = col_obj.yellow(header)
00604 h_line = col_obj.yellow(h_line)
00605 v_line = col_obj.yellow(v_line)
00606
00607 print header
00608 print h_line
00609 print " Nr. "+v_line+" Error Number\t"+v_line+" Frequency\t"+v_line+" Error Name\t\t\t"
00610 print h_line
00611
00612 if filus != None:
00613 content = " Nr. | Error Number\t| Frequency\t| Error Name\t\t\t\n\n"
00614 filus_fd.write(content)
00615
00616
00617 for i in range(len(table_error)):
00618 print " %5d %s %7s\t%s %6s\t%s %s" % ((i+1), v_line, table_error[i][0], v_line, table_error[i][1], v_line, table_error[i][2])
00619
00620
00621 if filus != None:
00622 content = " %5d | %7s\t| %6s\t| %s" % ((i+1), table_error[i][0], table_error[i][1], table_error[i][2])
00623 filus_fd.write(content)
00624
00625 print h_line
00626
00627 if filus != None:
00628 filus_fd.close()
00629
00630 elif graph == 1:
00631 if filus != None:
00632 gui.display_graph(data, col, file_fd = filus_fd)
00633 else:
00634 gui.display_graph(data, col)
00635
00636 if __name__ == '__main__':
00637
00638 start()
00639
00640
00641
00642
00643
00644
00645
00646
00647