#!/usr/bin/env python # -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 u"""%(scriptname)s: Afficher une requête SQL d'un fichier de log WebObjects USAGE %(scriptname)s 'line' cat /var/log/WebObjets/App-1 | %(scriptname)s Les fichiers de logs WebObjects, quand ils contiennent des requêtes SQL, ne sont pas exploitables directement: la requête et les arguments sont disjoints. Ce script fusionne la requête et les arguments pour générer une requête SQL utilisable directement. Il faut spécifier en argument la ligne complète du fichier de log, e.g. %(scriptname)s '[2012-11-07 09:58:31 GST]... "SELECT..." withBindings:...' Sinon, les lignes sont lues depuis l'entrée standard.""" import os, sys, re from os import path from ulib.all import * def display_help(): uprint(__doc__ % globals()) RE_NUMERIC = re.compile('\d+$') RE_QUOTED = re.compile(r'".*"$') def fixvalue(v): if RE_NUMERIC.match(v) is not None: # Les valeurs numériques sont données telles quelles return v if RE_QUOTED.match(v) is not None: # Les valeurs chaines sont entre guillemets return "'" + v[1:-1] + "'" # Sinon, on assume que c'est une date return "to_date('" + v + "', 'YYYY-MM-DD HH24:MI:SS')" RE_LINE = re.compile(r'[^"]*"([^"]*)" withBindings: (.*)>') RE_VAR = re.compile(r'\d+:(.*?)\(\w+\)') def fixsql(line, raiseerror=True): mo = RE_LINE.match(line) if mo is None: if raiseerror: raise ValueError("%s: Chaine invalide" % line) else: return None sql = mo.group(1) vars = map(fixvalue, RE_VAR.findall(mo.group(2))) for var in vars: pos = sql.index('?') if pos == -1: if raiseerror: raise ValueError("%s: Chaine invalide (nombre de ? non cohérent)" % line) else: return None sql = sql[:pos] + var + sql[pos+1:] return sql + ';' def run_wofixsql(): options, longoptions = build_options([ ('h', 'help', "Afficher l'aide"), ]) options, args = get_args(None, options, longoptions) for option, value in options: if option in ('-h', '--help'): display_help() sys.exit(0) if args: for arg in args: print fixsql(arg) else: while True: try: line = raw_input() except EOFError: break sql = fixsql(line, False) if sql is not None: print sql if __name__ == '__main__': run_wofixsql()