Merge "add level parameter to htmlify-screen-log"
This commit is contained in:
commit
1be295e9e3
@ -27,6 +27,16 @@ DATEFMT = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d{3})?'
|
|||||||
STATUSFMT = '(DEBUG|INFO|WARN|ERROR|TRACE|AUDIT)'
|
STATUSFMT = '(DEBUG|INFO|WARN|ERROR|TRACE|AUDIT)'
|
||||||
LOGMATCH = '(?P<date>%s)(?P<pid> \d+)? (?P<status>%s)' % (DATEFMT, STATUSFMT)
|
LOGMATCH = '(?P<date>%s)(?P<pid> \d+)? (?P<status>%s)' % (DATEFMT, STATUSFMT)
|
||||||
|
|
||||||
|
SEVS = {
|
||||||
|
'NONE': 0,
|
||||||
|
'DEBUG': 1,
|
||||||
|
'INFO': 2,
|
||||||
|
'AUDIT': 3,
|
||||||
|
'TRACE': 4,
|
||||||
|
'WARN': 5,
|
||||||
|
'ERROR': 6
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _html_close():
|
def _html_close():
|
||||||
return ("</span></pre></body></html>\n")
|
return ("</span></pre></body></html>\n")
|
||||||
@ -44,17 +54,34 @@ a:hover {text-decoration: underline}
|
|||||||
.TRACE, .TRACE a {color: #c60}
|
.TRACE, .TRACE a {color: #c60}
|
||||||
.WARN, .WARN a {color: #D89100; font-weight: bold}
|
.WARN, .WARN a {color: #D89100; font-weight: bold}
|
||||||
.INFO, .INFO a {color: #006; font-weight: bold}
|
.INFO, .INFO a {color: #006; font-weight: bold}
|
||||||
|
.selector, .selector a {color: #888}
|
||||||
|
.selector a:hover {color: #c00}
|
||||||
</style>
|
</style>
|
||||||
<body><pre><span>\n""")
|
<body>
|
||||||
|
<span class='selector'>
|
||||||
|
Display level: [
|
||||||
|
<a href='?'>ALL</a> |
|
||||||
|
<a href='?level=DEBUG'>DEBUG</a> |
|
||||||
|
<a href='?level=INFO'>INFO</a> |
|
||||||
|
<a href='?level=AUDIT'>AUDIT</a> |
|
||||||
|
<a href='?level=TRACE'>TRACE</a> |
|
||||||
|
<a href='?level=WARN'>WARN</a> |
|
||||||
|
<a href='?level=ERROR'>ERROR</a> ]
|
||||||
|
</span>
|
||||||
|
<pre><span>""")
|
||||||
|
|
||||||
|
|
||||||
def color_by_sev(line):
|
def sev_of_line(line, oldsev="NONE"):
|
||||||
"""Wrap a line in a span whose class matches it's severity."""
|
|
||||||
m = re.match(LOGMATCH, line)
|
m = re.match(LOGMATCH, line)
|
||||||
if m:
|
if m:
|
||||||
return "<span class='%s'>%s</span>" % (m.group('status'), line)
|
return m.group('status')
|
||||||
else:
|
else:
|
||||||
return line
|
return oldsev
|
||||||
|
|
||||||
|
|
||||||
|
def color_by_sev(line, sev):
|
||||||
|
"""Wrap a line in a span whose class matches it's severity."""
|
||||||
|
return "<span class='%s'>%s</span>" % (sev, line)
|
||||||
|
|
||||||
|
|
||||||
def escape_html(line):
|
def escape_html(line):
|
||||||
@ -80,8 +107,22 @@ def link_timestamp(line):
|
|||||||
return line
|
return line
|
||||||
|
|
||||||
|
|
||||||
def passthrough_filter(fname):
|
def skip_line_by_sev(sev, minsev):
|
||||||
|
"""should we skip this line?
|
||||||
|
|
||||||
|
If the line severity is less than our minimum severity,
|
||||||
|
yes we should"""
|
||||||
|
return SEVS.get(sev, 0) < SEVS.get(minsev, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def passthrough_filter(fname, minsev):
|
||||||
|
sev = "NONE"
|
||||||
for line in fileinput.FileInput(fname, openhook=fileinput.hook_compressed):
|
for line in fileinput.FileInput(fname, openhook=fileinput.hook_compressed):
|
||||||
|
sev = sev_of_line(line, sev)
|
||||||
|
|
||||||
|
if skip_line_by_sev(sev, minsev):
|
||||||
|
continue
|
||||||
|
|
||||||
yield line
|
yield line
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +144,7 @@ def does_file_exist(fname):
|
|||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
def html_filter(fname):
|
def html_filter(fname, minsev):
|
||||||
"""Generator to read logs and output html in a stream.
|
"""Generator to read logs and output html in a stream.
|
||||||
|
|
||||||
This produces a stream of the htmlified logs which lets us return
|
This produces a stream of the htmlified logs which lets us return
|
||||||
@ -111,9 +152,13 @@ def html_filter(fname):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
yield _css_preamble()
|
yield _css_preamble()
|
||||||
|
sev = "NONE"
|
||||||
for line in fileinput.FileInput(fname, openhook=fileinput.hook_compressed):
|
for line in fileinput.FileInput(fname, openhook=fileinput.hook_compressed):
|
||||||
newline = escape_html(line)
|
newline = escape_html(line)
|
||||||
newline = color_by_sev(newline)
|
sev = sev_of_line(newline, sev)
|
||||||
|
if skip_line_by_sev(sev, minsev):
|
||||||
|
continue
|
||||||
|
newline = color_by_sev(newline, sev)
|
||||||
newline = link_timestamp(newline)
|
newline = link_timestamp(newline)
|
||||||
yield newline
|
yield newline
|
||||||
yield _html_close()
|
yield _html_close()
|
||||||
@ -170,6 +215,14 @@ def should_be_html(environ):
|
|||||||
return accepts_html and not text_override
|
return accepts_html and not text_override
|
||||||
|
|
||||||
|
|
||||||
|
def get_min_sev(environ):
|
||||||
|
parameters = cgi.parse_qs(environ.get('QUERY_STRING', ''))
|
||||||
|
if 'level' in parameters:
|
||||||
|
return cgi.escape(parameters['level'][0])
|
||||||
|
else:
|
||||||
|
return "NONE"
|
||||||
|
|
||||||
|
|
||||||
def application(environ, start_response):
|
def application(environ, start_response):
|
||||||
status = '200 OK'
|
status = '200 OK'
|
||||||
|
|
||||||
@ -181,16 +234,17 @@ def application(environ, start_response):
|
|||||||
return ['Invalid file url']
|
return ['Invalid file url']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
minsev = get_min_sev(environ)
|
||||||
if should_be_html(environ):
|
if should_be_html(environ):
|
||||||
response_headers = [('Content-type', 'text/html')]
|
response_headers = [('Content-type', 'text/html')]
|
||||||
does_file_exist(logpath)
|
does_file_exist(logpath)
|
||||||
generator = html_filter(logpath)
|
generator = html_filter(logpath, minsev)
|
||||||
start_response(status, response_headers)
|
start_response(status, response_headers)
|
||||||
return generator
|
return generator
|
||||||
else:
|
else:
|
||||||
response_headers = [('Content-type', 'text/plain')]
|
response_headers = [('Content-type', 'text/plain')]
|
||||||
does_file_exist(logpath)
|
does_file_exist(logpath)
|
||||||
generator = passthrough_filter(logpath)
|
generator = passthrough_filter(logpath, minsev)
|
||||||
start_response(status, response_headers)
|
start_response(status, response_headers)
|
||||||
return generator
|
return generator
|
||||||
except IOError:
|
except IOError:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user