53 lines
1.3 KiB
Python
53 lines
1.3 KiB
Python
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
|