Files
oniagent/tools/event_daemon.py

98 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""
ONI Agent Event Daemon
======================
Continuous event poller. Polls game events every N seconds and displays
critical/warning/info events to the console (for AI input stream).
Usage:
python event_daemon.py [interval_seconds]
"""
import json, os, sys, time, datetime
TOOLS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'tools')
sys.path.insert(0, TOOLS_DIR)
from oni_api import api_get, api_post, load_config
POLL_INTERVAL = 5
MAX_EVENTS = 200
class EventHistory:
def __init__(self, maxlen=200):
self.events = []
self.maxlen = maxlen
self.last_seq = -1
self.stats = {"critical": 0, "warning": 0, "info": 0}
def add(self, event):
self.events.append(event)
if len(self.events) > self.maxlen:
self.events.pop(0)
sev = event.get('severity', 'info')
self.stats[sev] = self.stats.get(sev, 0) + 1
def get_recent(self, n=10):
return self.events[-n:]
def main():
interval = int(sys.argv[1]) if len(sys.argv) > 1 else POLL_INTERVAL
history = EventHistory(MAX_EVENTS)
consecutive_errors = 0
print(f"[EventDaemon] Starting — poll interval {interval}s")
print(f"[EventDaemon] Config: {json.dumps(load_config())}")
while True:
try:
r = api_get(f'/api/state/events?since={history.last_seq}')
if not r.get("success"):
consecutive_errors += 1
if consecutive_errors > 3:
print(f"[EventDaemon] {consecutive_errors} consecutive errors — mod may be offline")
time.sleep(interval)
continue
consecutive_errors = 0
data = r.get("data", {})
events = data.get("events", [])
next_seq = data.get("nextSeq", history.last_seq)
for ev in events:
history.add(ev)
sev = ev.get('severity', 'info')
title = ev.get('title', '')
message = ev.get('message', '')
ts = ev.get('timestamp', 0)
dt = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S') if ts else ''
if sev in ('critical', 'error'):
print(f"\n⚠️ [{dt}] CRITICAL: {title} {message}")
elif sev in ('warning',):
print(f"\n🟡 [{dt}] WARNING: {title} {message}")
else:
print(f"🔵 [{dt}] INFO: {title} {message}")
if events:
history.last_seq = next_seq
# Show summary every 30 seconds
if history.events and int(time.time()) % 30 < interval:
c = history.stats.get('critical', 0)
w = history.stats.get('warning', 0)
print(f"[EventDaemon] Stats | critical={c} warning={w} total={len(history.events)} | seq={history.last_seq}")
except KeyboardInterrupt:
print("\n[EventDaemon] Stopped")
break
except Exception as ex:
print(f"[EventDaemon] Error: {ex}")
time.sleep(interval)
continue
time.sleep(interval)
if __name__ == "__main__":
main()