import time import json from collections import defaultdict class EventJournal: def __init__(self): # immutable append-only log self.events = [] # indexed views for fast debug queries self.by_action = defaultdict(list) self.by_node = defaultdict(list) # ----------------------------- # WRITE EVENT # ----------------------------- def record(self, event_type, payload): event = { "ts": time.time(), "type": event_type, "data": payload } self.events.append(event) if "action" in payload: self.by_action[payload["action"]].append(event) if "node" in payload: self.by_node[payload["node"]].append(event) # ----------------------------- # QUERY ACTION TRACE # ----------------------------- def trace_action(self, action_name): return self.by_action.get(action_name, []) # ----------------------------- # QUERY NODE TRACE # ----------------------------- def trace_node(self, node_name): return self.by_node.get(node_name, []) # ----------------------------- # FULL REPLAY STREAM # ----------------------------- def replay(self): for event in sorted(self.events, key=lambda e: e["ts"]): yield event