diff options
author | navid <navid@ef72aa8b-4018-0410-8976-d6e080ef94d8> | 2007-11-22 10:40:27 +0000 |
---|---|---|
committer | navid <navid@ef72aa8b-4018-0410-8976-d6e080ef94d8> | 2007-11-22 10:40:27 +0000 |
commit | e2ea89dbbe1b1731ba4eda7fbe40ea315594a1c9 (patch) | |
tree | affd667e6f91c207a1c497ad895f336f0f386f59 /src/extras/htmlog | |
parent | e60df25b9b22ec1bf78d8d95ca7673d559f13333 (diff) | |
download | sos-e2ea89dbbe1b1731ba4eda7fbe40ea315594a1c9.tar.gz |
merged navid-dev back into trunk, see spec file for details
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/sos/trunk@457 ef72aa8b-4018-0410-8976-d6e080ef94d8
Diffstat (limited to 'src/extras/htmlog')
-rwxr-xr-x | src/extras/htmlog | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/src/extras/htmlog b/src/extras/htmlog deleted file mode 100755 index 87d9e9c1..00000000 --- a/src/extras/htmlog +++ /dev/null @@ -1,473 +0,0 @@ -#!/usr/bin/env python - -#from optparse import OptionParser, Option -import time, sys, os, glob -import getopt, re - -#__cmdParser__ = OptionParser() -#__cmdParser__.add_option("-i", "--input", action="append", -# dest="logfiles", type="string", metavar = "FILE", -# help="system log to parse") -#__cmdParser__.add_option("-v", "--verbose", action="count", -# dest="verbosity", -# help="How obnoxious we're being about telling the user what we're doing.") -#(__cmdLineOpts__, __cmdLineArgs__)=__cmdParser__.parse_args() - -class htmlgen_class: - - def __init__(self): - self.html_fname_base = "/tmp/something" - self.page_num = 0 - self.page_line = 0 - self.page_fp = None - self.cur_time = None - self.old_time = None - - self.summary_fp = open(self.html_fname_base + ".html", "w") - self.summary_fp.write("<html><body><ul>") - - def new_page(self): - - # close previous page - if self.page_fp: - self.close_page() - - self.page_fp = open( "%s_%d.html" % (self.html_fname_base, self.page_num), "w") - self.page_num += 1 - self.page_line = 0 - - self.page_fp.write("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> - -<html> -<head> -<title></title> -<style type="text/css"> -<!-- - -body { - font: normal 11px auto "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; - color: #4f6b72; - background: #E6EAE9; -} - -a { - color: #c75f3e; -} - -#mytable { - width: 97%; - padding: 0; - margin: 0; -} - -caption { - padding: 0 0 5px 0; - width: 97%; - font: italic 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; - text-align: right; -} - -th { - font: bold 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; - color: #4f6b72; - letter-spacing: 2px; - text-transform: uppercase; - text-align: left; - padding: 6px 6px 6px 12px; - background: #a50000 url(images/bg_header.jpg) no-repeat; - color: white; -} - -th.nobg { - border-top: 0; - border-left: 0; - border-right: 1px solid #C1DAD7; - background: none; - color: black; -} - -td { - border-right: 1px solid #C1DAD7; - border-bottom: 1px solid #C1DAD7; - background: #fff; - padding: 6px 6px 6px 12px; - color: #4f6b72; - letter-spacing: -1px; - white-space:pre-wrap; - font-family: monospace; -} - -pre { - white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ -} - -td.alt { - background: #ffbaba; - color: #797268; -} - -th.newday { - text-align: right; - padding: 2px; -} - -th.spec { - border-left: 1px solid #C1DAD7; - border-right: 1px solid #C1DAD7; - border-top: 0; - background: #fff url(images/bullet1.gif) no-repeat; - font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; - color: #797268; -} - -th.specalt { - border-left: 1px solid #C1DAD7; - border-right: 1px solid #C1DAD7; - border-top: 0; - background: #cecfce url(images/bullet2.gif) no-repeat; - font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; - color: #797268; -} - ---> -</style> - -</head> -<body> - -<table id="mytable" cellspacing="0" summary="The technical specifications of the Apple PowerMac G5 series"> -<caption>Generated by SOS htmlogger 1.0 on March 16th 2008</caption> -""") - - def new_line(self, new_time, events = []): - self.old_time = self.cur_time - self.cur_time = new_time - - # close previous line - if self.page_line > 0: - self.page_fp.write("</TR>") - - if self.page_line == 0 or self.page_line % 200 == 0: - self.page_fp.write("""<tr><th scope="col" abbr="Date/Time" class="nobg">Time</th><th scope="col" abbr="node-1">node-1</th><th scope="col" abbr="node-2">node-2</th><th scope="col" abbr="node-3">node-3</th></tr>""") - - if self.page_line == 0 or self.page_line % 200 == 0 or time.strftime("%b %d", self.old_time) != time.strftime("%b %d", new_time): - self.page_fp.write("""<tr><th scope="row" class="newday" colspan=4>%s</th></tr>""" % time.strftime("%A, %B %d", new_time)) - - if self.page_line % 2 == 0: row_class = "spec" - else: row_class = "specalt" - - if len(events) > 0: - stime = """<a name="row_%d">%s</a>""" % (self.page_line, time.strftime("%H:%M:%S", new_time)) - for event in events: - self.summary_fp.write('<li><a href="something_%d.html#row_%s">%s</a>' % (self.page_num-1,self.page_line,event) ) - else: - stime = time.strftime("%H:%M:%S", new_time) - - if not self.old_time or self.old_time != new_time: - self.page_fp.write("""<TR><th scope="row" class="%s">%s</th>""" % (row_class, stime)) - else: - self.page_fp.write("""<TR><th scope="row" class="%s" style="color: #cacaca">%s</th>""" % (row_class, stime)) - - self.page_line+=1 - - def new_tab(self,msg): - self.page_fp.write(" <TD>" + msg + "</TD>\n") - - def close_page(self): - self.page_fp.write("</table></html>\n") - self.page_fp.close() - - def finish(self): - self.close_page() - -class host_class: - - def __init__(self): - self.logs = [] - - self.log_idx = 0 # first log - self.log_ptr = 0 # first char - - self.cur_line = None - - def add_log(self, logfile): -# if not logfile == logfile_class: -# raise "InvalidLogfile" - - for inc in range(0,len(self.logs)): - if logfile.time_end() < self.logs[inc].time_begin(): - self.logs.insert(inc, logfile) - break - else: - self.logs.append(logfile) - - def hostname(self): - try: return self.logs[0].hostname() - except: return None - - def tell(self): - sumsize = 0 - if self.log_idx > 0: - for inc in range(0, self.log_idx): - sumsize += self.logs[inc].size() - try: - sumsize += self.fp().tell() - except TypeError: - pass - return sumsize - - def size(self): - sumsize = 0 - for inc in range(0, len(self.logs)): - sumsize += self.logs[inc].size() - return sumsize - - def eof(self): - if self.tell() >= self.size(): - return True - return False - - def seek(self, offset, whence = 0): - if whence == 1: offset = self.tell() + offset - elif whence == 2: offset = self.size() + offset - - sumsize = 0 - for inc in range(0, len(self.logs)): - if offset <= sumsize + self.logs[inc].size(): - offset -= sumsize - self.log_idx = inc - self.log_ptr = offset - self.logs[inc].seek(offset) - return True - sumsize += self.logs[inc].size() - raise "Off_Boundaries" - - def time(self): - return time.strptime(self.cur_line[0:15], "%b %d %H:%M:%S") - pos = self.tell() - try: - toret = time.strptime(self.readline()[0:15], "%b %d %H:%M:%S") - except ValueError: - toret = None - self.seek(pos) - return toret - - def fp(self): - return self.logs[self.log_idx] - - def backline(self): - self.seek(-len(self.cur_line), 1) - - def readline(self): - if self.eof(): - return "" - - while True: - toret = self.fp().readline() - if len(toret) == 0: - if self.log_idx < len(self.logs): - self.log_idx += 1 - self.fp().seek(0) - continue - else: - return "" - - if self.validate_line(toret) or toret == "": - self.cur_line = toret - return toret - else: - print "invalid line" - - def validate_line(self, line): - try: - time.strptime(line[0:15], "%b %d %H:%M:%S") - except: - return False - return True - - def cur_msg(self): - if not hasattr(self,"_regex_cur_msg"): - self._regex_cur_msg = re.compile(r"""^.* %s (\S+:.*)$""" % self.hostname()) - - try: return self._regex_cur_msg.findall(self.cur_line)[0] - except: return self.cur_line - -class logfile_class: - - def __init__(self,fname): - self.events = [] - self.fname = fname - self.fp = open(fname) - - def hostname(self): - pos = self.fp.tell() - toret = self.fp.readline()[16:].split(" ")[0] - self.fp.seek(pos) - return toret - - def time_begin(self): - pos = self.fp.tell() - self.fp.seek(0) - toret = time.strptime(self.fp.readline()[0:15], "%b %d %H:%M:%S") - self.fp.seek(pos) - return toret - - def time_end(self): - pos = self.fp.tell() - bs = 1024 - if self.size() < bs: bs = self.size() - self.fp.seek(-bs, 2) - line = self.fp.read(bs) - toret = time.strptime(line[line.rfind("\n", 0, bs - 1) + 1:][0:15], "%b %d %H:%M:%S") - self.fp.seek(pos) - return toret - - def size(self): - return os.path.getsize(self.fname) - - def eof(self): - return self.fp.tell() > self.size() - - def readline(self): - return self.fp.readline() - - def seek(self,pos): - self.fp.seek(pos) - - def tell(self): - return self.fp.tell() - - def validate_line(self): - return self.time_current(self.curmessage()) - - def time_current(self): - if len(self.curline) == 0: return None - try: - return time.strptime(self.curline[0:15], "%b %d %H:%M:%S") - except ValueError: - print "could not parse time", self.curline - return False - -def usage(): - print "ciao" - -try: - opts, args = getopt.getopt(sys.argv[1:], "hi:v", ["help", "input="]) -except getopt.GetoptError: - # print help information and exit: - usage() - sys.exit(2) - -cmdline = {} -cmdline["logfiles"] = [] - -for o, a in opts: - if o == "-v": - verbose = True - if o in ("-h", "--help"): - usage() - sys.exit() - if o in ("-i", "--input"): - print o,a - for fname in sys.argv[2:]: - cmdline["logfiles"].append(fname) - sys.stderr.write("adding log %s\n" % fname) - -hosts = {} - -for logname in cmdline["logfiles"]: - log = logfile_class(logname) - hostname = log.hostname() - sys.stderr.write("log %s for host %s\n" % (logname, hostname)) - if not hosts.has_key(hostname): - hosts[hostname] = host_class() - hosts[hostname].add_log(log) - -sys.stderr.write("finished adding logs\n") - -#print '<ul id="toc">' -#for log in logs: -# print logs[idx].fname, logs[idx].events -# for line, msglen, event in log.events: -# print ' <li><span>%s</span> <a href="#">Link</a><br /></li>' % event - -htmlgen = htmlgen_class() - -previous_date = None - -while True: - # who is next ? - lowest_date = None - for host in hosts: - if hosts[host].eof(): - continue - - hosts[host].readline() - - if lowest_date == None or hosts[host].time() < lowest_date: - lowest_date = hosts[host].time() - - if lowest_date == None: - # all logs are EOF - break - - events = [] - for host in hosts: - if hosts[host].time() == lowest_date: - - if re.match(r'^kernel: Linux version', hosts[host].cur_msg()): - events.append("%s rebooted" % host) - - elif re.match(r'^.*fencing node', hosts[host].cur_msg()): - events.append(host + " " + hosts[host].cur_msg()) - - elif re.match(r'.*fence ".*" success', hosts[host].cur_msg()): - events.append(host + " " + hosts[host].cur_msg()) - - elif re.match(r'.*fence ".*" failed', hosts[host].cur_msg()): - events.append(host + " " + hosts[host].cur_msg()) - - elif re.match(r'.*quorum lost, blocking activity', hosts[host].cur_msg()): - events.append(host + " " + hosts[host].cur_msg()) - - elif re.match(r'.*quorum regained, resuming activity', hosts[host].cur_msg()): - events.append(host + " " + hosts[host].cur_msg()) - - elif re.match(r'.*segfault at', hosts[host].cur_msg()): - events.append(host + " " + hosts[host].cur_msg()) - - elif not hosts[host].eof(): - hosts[host].backline() - - if len(events): print time.strftime("%A %B %d %H:%M:%S", lowest_date), events - - if htmlgen.page_line == 0 or htmlgen.page_line > 10000: - print "creating new page #%d" % htmlgen.page_num - htmlgen.new_page() - - htmlgen.new_line(lowest_date, events) - - for host in hosts: - if hosts[host].time() == lowest_date: - htmlgen.new_tab(hosts[host].cur_msg()) - else: - htmlgen.new_tab("") - -htmlgen.close_page() - - - - - - - - - - - - |