""" precti_trace.py – přehledné SQL dotazy z Firebird audit trace logu Čte od konce (nejnovější nahoře). Použití: python precti_trace.py # posledních 50 dotazů python precti_trace.py 100 # posledních 100 python precti_trace.py 50 SELECT # filtr – jen SELECT dotazy """ import re, sys, io LOG_PATH = r'C:\Program Files\Firebird\Firebird_2_5_CGM\default_trace.log' SEPARATOR = '-' * 80 TS_RE = re.compile(r'^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+)\s+\([\w:]+\)\s+(\w+)') ATT_RE = re.compile(r'\(ATT_\d+,\s*([\w]+):') SQL_S_RE = re.compile(r'^-{70,}$') SQL_E_RE = re.compile(r'^\^{70,}$') # ── Parametry ────────────────────────────────────────────────────────────── limit = int(sys.argv[1]) if len(sys.argv) > 1 else 50 filtr = sys.argv[2].upper() if len(sys.argv) > 2 else '' # ── Čtení logu ───────────────────────────────────────────────────────────── with open(LOG_PATH, 'r', encoding='cp1252', errors='replace') as f: lines = f.readlines() # ── Rozděl log na bloky podle timestamp řádků ────────────────────────────── # Každý blok = od jednoho timestamp řádku do dalšího blocks = [] # (start_line_idx, ts, event, block_lines[]) i = 0 n = len(lines) while i < n: m = TS_RE.match(lines[i].rstrip()) if m: ts = m.group(1) event = m.group(2) start = i i += 1 block = [] while i < n and not TS_RE.match(lines[i].rstrip()): block.append(lines[i].rstrip()) i += 1 blocks.append((ts, event, block)) else: i += 1 # ── Extrahuj SQL z PREPARE_STATEMENT bloků ───────────────────────────────── results = [] for ts, event, block in blocks: if event != 'PREPARE_STATEMENT': continue # Uživatel user = '?' for line in block: att = ATT_RE.search(line) if att: user = att.group(1) break # SQL mezi --- a ^^^ sql_lines = [] plan_lines = [] in_sql = False after_sql = False for line in block: if SQL_S_RE.match(line): in_sql = True after_sql = False continue if SQL_E_RE.match(line): in_sql = False after_sql = True continue if in_sql: sql_lines.append(line) elif after_sql and line.startswith('PLAN'): plan_lines.append(line) sql = '\n'.join(sql_lines).strip() plan = ' '.join(plan_lines).strip() if sql: results.append((ts, user, sql, plan)) # ── Výstup – nejnovější nahoře ───────────────────────────────────────────── sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') filtered = [r for r in results if filtr in r[2].upper()] if filtr else results filtered = list(reversed(filtered))[:limit] print(f'Firebird trace – posledních {len(filtered)} dotazu' + (f' [filtr: {filtr}]' if filtr else '')) print(SEPARATOR) for ts, user, sql, plan in filtered: print(f'[{ts}] {user}') print(sql) if plan: print(f' --> {plan}') print(SEPARATOR)