import sys, os
from Ft.Xml.Xslt import Transform
"""
log2html.py is a script that takes a SQL prevent log as input, and produces an html representation as output.
"""
USAGE = """
usage:
log2html.py <sqlprevent_application.log>
"""
__author__ = 'Levi Stoddard'
__date__ = 'May 20th, 2009'
# get log file to parse
if len(sys.argv) != 2:
print(USAGE)
exit(1)
input_file = sys.argv[1]
# read xml to transform
xml_file = open(input_file, 'r')
xml_str = "<log>%s</log>" % xml_file.read()
xml_file.close()
# xslt that will be applied to the log file
xslt_str = """
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="date">
<xsl:output method="html"
indent="yes"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
<xsl:template match="/">
<html>
<head>
<style type="text/css">
/*
* query styles
*/
tr.query { background: blue; }
tr.specifics { background: yellow; }
tr.even { background: #99DDFF; }
tr.odd { background: #99BBFF; }
.tainted { color: red; }
/*
* error styles
*/
tr.error { background: red; }
</style>
</head>
<body>
<h1><xsl:value-of select="concat('SQL Prevent Log (', date:date-time(), ')')" /></h1>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="log">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="error|query">
<xsl:variable name="name" select="name()"/>
<p>
<table border="1">
<xsl:call-template name="header">
<xsl:with-param name="title"><xsl:value-of select="$name" /></xsl:with-param>
<xsl:with-param name="class"><xsl:value-of select="$name" /></xsl:with-param>
</xsl:call-template>
<xsl:apply-templates />
</table>
</p>
</xsl:template>
<xsl:template match="performance">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="statement">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="time-start|time-stop|time-delta|benign|time|msg|trace">
<tr>
<td><xsl:value-of select="concat(name(), ': ')" /></td>
<td><xsl:value-of select="." /></td>
</tr>
</xsl:template>
<xsl:template match="sql">
<tr>
<td>sql:</td>
<td>
<xsl:apply-templates />
</td>
</tr>
</xsl:template>
<xsl:template match="tainted|clean">
<span>
<xsl:attribute name="class">
<xsl:value-of select="name()" />
</xsl:attribute>
<xsl:value-of select="." />
</span>
</xsl:template>
<xsl:template match="specifics">
<xsl:if test="count(./*) > 0">
<xsl:call-template name="header">
<xsl:with-param name="title">specifics</xsl:with-param>
<xsl:with-param name="class">specifics</xsl:with-param>
</xsl:call-template>
<xsl:for-each select="./*">
<tr>
<!-- give rows alternating colors-->
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="position() mod 2 = 1">odd</xsl:when>
<xsl:otherwise>even</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<!-- node name -->
<td>
<xsl:value-of select="name()" />
</td>
<!-- node value/attributes -->
<td>
<xsl:value-of select="." />
<xsl:for-each select="./@*">
<xsl:value-of select="concat(' (', name(), ': ', ., ')')"/>
</xsl:for-each>
</td>
</tr>
</xsl:for-each>
</xsl:if>
</xsl:template>
<xsl:template name="header">
<xsl:param name="title" />
<xsl:param name="class" />
<tr>
<xsl:attribute name="class"><xsl:value-of select="$class"/></xsl:attribute>
<th><xsl:value-of select="$title" /></th>
<th></th>
</tr>
</xsl:template>
</xsl:stylesheet>
"""
# transform against xslt, and write to output file
result = Transform(xml_str, xslt_str)
base_name = os.path.splitext(input_file)[0]
html_file = open("%s.html" % base_name, 'w+')
html_file.write(result)
html_file.close()
print("html output written to %s" % html_file.name)