import re import json from dataclasses import dataclass, field, asdict from datetime import datetime from typing import Optional # ── Preprocessing ──────────────────────────────────────────────────────────── _TS_RE = re.compile(r'^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\]\s*') _CHILD_RE = re.compile(r'^\[(\d+)\]\s*') def strip_ts(line: str) -> str: """Remove optional `ts`-injected timestamp prefix from a log line.""" return _TS_RE.sub('', line.strip()) def classify_line(line: str) -> tuple[str, Optional[int], str]: """ Return (kind, port, content) where kind is 'router' or 'child'. `line` must already have the ts prefix stripped. """ m = _CHILD_RE.match(line) if m: return ('child', int(m.group(1)), line[m.end():]) return ('router', None, line)