58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Summarize LLM_CONNECT_* records from a DeerFlow backend log."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
RUN_RE = re.compile(r"run_id=([^ ]+)")
|
|
VALUE_RE = re.compile(r"(first_chunk_ms|total_ms)=([^ ]+)")
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("log", nargs="?", type=Path, help="Log file; omit to read stdin")
|
|
args = parser.parse_args()
|
|
text = args.log.read_text(encoding="utf-8", errors="replace") if args.log else sys.stdin.read()
|
|
|
|
calls: dict[str, dict[str, str]] = {}
|
|
for line in text.splitlines():
|
|
if "LLM_" not in line:
|
|
continue
|
|
run_match = RUN_RE.search(line)
|
|
if not run_match:
|
|
continue
|
|
run_id = run_match.group(1)
|
|
row = calls.setdefault(run_id, {"run_id": run_id, "status": "started"})
|
|
if "LLM_CONNECT_OK" in line:
|
|
row["status"] = "connected"
|
|
if "LLM_REQUEST_DONE" in line:
|
|
row["status"] = "success"
|
|
if "LLM_REQUEST_FAILED" in line:
|
|
row["status"] = "failed"
|
|
for key, value in VALUE_RE.findall(line):
|
|
row[key] = value
|
|
|
|
print("run_id status first_chunk_ms total_ms")
|
|
for row in calls.values():
|
|
print(
|
|
row["run_id"],
|
|
row.get("status", "-"),
|
|
row.get("first_chunk_ms", "-"),
|
|
row.get("total_ms", "-"),
|
|
)
|
|
|
|
succeeded = sum(row.get("status") == "success" for row in calls.values())
|
|
failed = sum(row.get("status") == "failed" for row in calls.values())
|
|
unfinished = len(calls) - succeeded - failed
|
|
print(f"SUMMARY calls={len(calls)} success={succeeded} failed={failed} unfinished={unfinished}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|