Skip to content

kg retrieval logs merge - #140

Merged
maximusunc merged 3 commits into
mainfrom
claude/kg-retrieval-logs-merge-m4tvyg
Aug 24, 2026
Merged

kg retrieval logs merge#140
maximusunc merged 3 commits into
mainfrom
claude/kg-retrieval-logs-merge-m4tvyg

Conversation

@maximusunc

@maximusunc maximusunc commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Include Retriever/Gandalf logs in the final message response

claude added 3 commits August 23, 2026 01:53
The subservices that do the actual knowledge-graph retrieval report their
work -- which KPs they called, what timed out, why an edge came back empty
-- in the TRAPI `logs` list of the response they POST to /callback. The
merge only ever built a fresh message (or, on the direct-lookup path,
returned the callback message whose logs finish_query then shadows with
the ones spliced in from the log store), so those entries were dropped and
never reached the query's log list.

Lift them off each callback in the merge child and hand them back with the
child's own records, so the parent folds them into the query logger and
save_logs flushes them alongside everything else. Entries below the query's
requested log level are dropped, malformed `logs` fields are survivable,
and MERGE_MAX_CALLBACK_LOGS (default 1000) caps how many entries a single
callback can contribute so a chatty subservice can't flood the query's logs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012QwdpTHjvsiTS1wfuq395b
The duplication had nothing to do with the callbacks themselves -- two
pre-existing bugs in the log plumbing compounded, and folding the KG
retrieval logs into that plumbing made them obvious.

_build_task_context builds "a logger per task" with logging.getLogger, but
the name is keyed on the query, so every task a worker runs for that query
lands on the same process-wide logger object -- and each one added another
QueryLogHandler to it. save_logs then picked whichever handler came first
and, crucially, never emptied it. So the first handler accumulated every
record for the query for the life of the process, and each task's flush
wrote the whole pile again: the Nth callback's merge re-persisted the
previous N-1 callbacks' logs. merge_message feels this hardest, since a
query gets one wake task per callback.

- QueryLogHandler.drain() empties the queue as it hands the records over,
  so a later flush of the same handler can't write them a second time. A
  failed write puts them back (they're nowhere else now).
- attach_query_handler() reuses a handler the logger already has instead of
  stacking another. Applied to the task/worker loggers and to the server
  routes -- /response built its handler on a fixed logger name, so it grew
  one per request.
- Since flushing is now destructive, a lost write would lose logs rather
  than duplicate them: store the logs as a Redis list that each flush
  appends to (atomically, with the TTL refresh in the same round trip)
  instead of rewriting the whole array read-modify-write. A query has
  several concurrent log producers -- the callback handler, each worker
  stage, one merge task per callback -- so those rewrites were racing.
  A key still holding the old whole-blob format is converted in place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012QwdpTHjvsiTS1wfuq395b
One query fans out into many retrievals whose logs all land in a single
list, so an untagged "KP timed out" line says nothing about which retrieval
it came from. Prefix every entry taken off a callback with [callback_id] --
the same tag the callback handler and the merge already use -- so a line
joins up with the rest of that retrieval's trail.

The lookup end of that trail was missing at the default log level: the
dispatch was logged at DEBUG (with the id only buried in the callback URL),
and BTE's direct path logged nothing at all. Log it at INFO with the tag in
all four dispatch sites, and name the id on the lookup-failed lines, which
had it available and didn't print it.

A query's logs now read:

    [a1b2c3d4] Sending lookup query to http://retrieval/asyncquery
    [a1b2c3d4] Got back 12 results.
    [a1b2c3d4] Querying KP infores:automat-robokop
    [a1b2c3d4] KP infores:text-mining timed out after 30s
    [a1b2c3d4] Merged 1 callback(s) in 0.42s

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012QwdpTHjvsiTS1wfuq395b
@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.31818% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.95%. Comparing base (6f97a21) to head (667465e).
⚠️ Report is 50 commits behind head on main.

Files with missing lines Patch % Lines
shepherd_server/base_routes.py 50.00% 2 Missing ⚠️
shepherd_utils/db.py 93.54% 1 Missing and 1 partial ⚠️
workers/merge_message/worker.py 96.77% 1 Missing ⚠️
Files with missing lines Coverage Δ
shepherd_utils/config.py 95.32% <100.00%> (+0.08%) ⬆️
shepherd_utils/logger.py 100.00% <100.00%> (+3.92%) ⬆️
shepherd_utils/shared.py 77.03% <100.00%> (+1.72%) ⬆️
workers/aragorn_lookup/worker.py 76.44% <100.00%> (+0.22%) ⬆️
workers/aragorn_pathfinder/worker.py 63.71% <100.00%> (+0.65%) ⬆️
workers/bte_lookup/worker.py 85.45% <100.00%> (+0.20%) ⬆️
workers/merge_message/worker.py 68.54% <96.77%> (+1.81%) ⬆️
shepherd_server/base_routes.py 39.67% <50.00%> (+0.10%) ⬆️
shepherd_utils/db.py 63.54% <93.54%> (+1.45%) ⬆️

... and 4 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 853abd1...667465e. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@maximusunc
maximusunc merged commit 0b1ed1f into main Aug 24, 2026
2 checks passed
@maximusunc
maximusunc deleted the claude/kg-retrieval-logs-merge-m4tvyg branch August 24, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants