From 407819b6470a65664d0bb6a2db9ca69794f90f72 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Tue, 4 Aug 2026 11:43:13 +0700 Subject: [PATCH] fix: parse PR-Agent analytics record-wrapped JSON format Real PR-Agent analytics logs wrap fields under 'record': {...}. The parser now unwraps that before extracting command/pr_url/message/level, so /api/analytics and /api/metrics show real data (verified with actual format from production logs). --- run_server.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/run_server.py b/run_server.py index b63295f..a5be52b 100644 --- a/run_server.py +++ b/run_server.py @@ -64,7 +64,14 @@ app.include_router(pr_router) # ── Analytics / Metrics ───────────────────────────────────────────────────── def _read_analytics_logs(max_files: int = 5) -> list: - """Parse PR-Agent analytics JSON logs (analytics=True records).""" + """Parse PR-Agent analytics JSON logs (analytics=True records). + + Real log lines look like: + {"text": "...", "record": {"elapsed": {...}, "extra": {"command": "...", "pr_url": "..."}, + "file": {...}, "function": "...", "level": {"name": "INFO", ...}, + "message": "...", "module": "...", "process": {...}, "thread": {...}, + "time": {"repr": "2026-08-04 ...", "timestamp": ...}}} + """ records = [] files = sorted(glob.glob(os.path.join(ANALYTICS_DIR, "pr-agent.*.log"))) for f in files[-max_files:]: @@ -78,7 +85,9 @@ def _read_analytics_logs(max_files: int = 5) -> list: rec = json.loads(line) except json.JSONDecodeError: continue - # Normalize structure: {message, extra{...}} + # PR-Agent wraps under "record": {...} + if "record" in rec and isinstance(rec["record"], dict): + rec = rec["record"] extra = rec.get("extra", {}) or {} if "artifact" in extra and isinstance(extra["artifact"], dict): extra.update(extra.pop("artifact"))