Merge pull request 'Mirror trace steps to the operational logger' (#32) from feat/per-step-logging into main

Reviewed-on: #32
Reviewed-by: archeious <archeious@unbiasedgeek.com>
This commit is contained in:
archeious 2026-04-08 22:23:01 +00:00
commit d51f16d33e

View file

@ -14,6 +14,27 @@ import uuid
from pathlib import Path
from typing import Any, Optional
from obs import get_logger
# Actions that get promoted to INFO in the operational log. Everything
# else logs at DEBUG so the default INFO level shows ~6-8 milestones per
# research call instead of 20+ chatty per-step events. Set
# MARCHWARDEN_LOG_LEVEL=DEBUG to see all steps.
_INFO_ACTIONS = frozenset(
{
"start",
"iteration_start",
"synthesis_start",
"synthesis_complete",
"synthesis_error",
"synthesis_build_error",
"budget_exhausted",
"complete",
}
)
_log = get_logger("marchwarden.researcher.trace")
class TraceLogger:
"""Logs research steps to a JSONL file.
@ -74,6 +95,14 @@ class TraceLogger:
self._writer.write(json.dumps(entry, default=str) + "\n")
self._writer.flush()
# Mirror the trace step into the operational logger so admins
# can watch progress in real time. trace_id and researcher are
# already bound in contextvars by WebResearcher.research, so
# they automatically appear on every line.
log_method = _log.info if action in _INFO_ACTIONS else _log.debug
log_method(action, step=self._step_counter, decision=decision, **kwargs)
return entry
def read_entries(self) -> list[dict]: