Skip to content

fix(bridge): stop root logger gating INFO out of bot.log#323

Merged
jinon86 merged 2 commits into
mainfrom
claude/a2a-broker-test-results-7vfj9r
Jul 8, 2026
Merged

fix(bridge): stop root logger gating INFO out of bot.log#323
jinon86 merged 2 commits into
mainfrom
claude/a2a-broker-test-results-7vfj9r

Conversation

@jinon86

@jinon86 jinon86 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

bot.log on quiet nodes sits at 0 bytes and INFO-level operational markers never appear — which made a memory-loss investigation impossible to diagnose from logs. Root cause: setup_logging() gates the root logger at WARNING in non-debug mode, so every INFO record is dropped before it can reach the INFO-level file handler.

The bug

console_level = log_level if is_debug else logging.WARNING
logging.basicConfig(level=console_level, ...)   # sets ROOT level to WARNING
fh = logging.FileHandler(logs_dir / "bot.log", ...)
fh.setLevel(log_level)                           # file handler wants INFO
logging.getLogger().addHandler(fh)

The root logger's level is a hard gate applied before any handler's own level — a record below it is discarded and never dispatched. Setting the root to WARNING therefore defeats fh.setLevel(INFO): the file handler can only filter records the logger already passed, and it never receives INFO. Net effect: bot.log captures WARNING+ only. A quiet node produces no WARNING+, so the file stays empty, and INFO diagnostics (boot banners, the Ignoring persisted session_id session-resume trace, etc.) are invisible.

Reproduced directly: with the root at WARNING, logger.info("Ignoring persisted session_id …") is absent from the file while a logger.warning(...) on the same run is present.

The fix

Set the root to log_level (INFO) so the file handler receives INFO, and gate the console StreamHandler per-handler at console_level (WARNING in non-debug) so stdout stays quiet:

logging.basicConfig(level=log_level, ...)
for _h in logging.getLogger().handlers:
    _h.setLevel(console_level)   # console quiet; root passes INFO to the file handler

Verified after the change: INFO markers reach bot.log while the console still suppresses them (only WARNING+ on stdout).

Test plan

  • Standalone repro confirms before/after behavior (INFO dropped → INFO written; console stays WARNING).
  • bridge/tests/test_logging_levels.py pins the invariant (root ≤ INFO, a file handler at ≤ INFO, console handlers ≥ WARNING). Skips cleanly where pydantic isn't installed; runs on CI.

Context

This unblocks the follow-up investigation into within-conversation memory loss on Termux nodes: the smoking-gun marker for the suspected cause (Ignoring persisted session_id, logged at INFO) was being silently discarded, so the log-based diagnostic could not see it. With INFO restored to bot.log, re-running the diagnostic after a repro will show whether the bridge is restarting between messages and refusing to resume the persisted session.

🤖 Generated with Claude Code

https://claude.ai/code/session_017rAPKfsLfaYqNY8iPXWX34


Generated by Claude Code

setup_logging() did `logging.basicConfig(level=WARNING)` in non-debug mode,
which sets the ROOT logger level to WARNING. The root level is a hard gate
applied before any handler's own level — records below it are dropped and never
dispatched. So every INFO record (boot banners AND operational markers like the
"Ignoring persisted session_id" session-resume trace) was discarded before it
could reach the INFO-level bot.log file handler. bot.log only ever captured
WARNING+, which is why a quiet node's bot.log sits at 0 bytes and INFO-level
diagnostics are invisible.

Set the root to log_level (INFO) so the file handler receives INFO, and gate the
console StreamHandler per-handler at console_level (WARNING in non-debug) so
stdout stays quiet. Verified: INFO markers now reach the file while the console
still suppresses them. (+ regression test, skips where pydantic isn't installed)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rAPKfsLfaYqNY8iPXWX34
@jinon86 jinon86 requested a review from seoseo-ai as a code owner July 8, 2026 00:02

@seoseo-ai seoseo-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검증 완료: CI pass, local targeted logging test pass, harness pass, diff/secret scan clean. Reviewer fix added to force root logger level under existing handlers.

@jinon86 jinon86 merged commit 97ec82a into main Jul 8, 2026
7 checks passed
@jinon86 jinon86 deleted the claude/a2a-broker-test-results-7vfj9r branch July 8, 2026 01:00

@seoseo-ai seoseo-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after diff review and green CI. Local verification: ruff on changed files passed; bridge regression test passed; full bridge pytest passed.

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.

3 participants