notebookvb
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
"""
|
||||
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)
|
||||
Reference in New Issue
Block a user