fix(logging): attach gateway log after cli init#16229
Merged
teknium1 merged 1 commit intoApr 27, 2026
Merged
Conversation
teknium1
added a commit
that referenced
this pull request
May 29, 2026
) External rotation (logrotate, manual `mv gateway.log gateway.log.1`, another process rotating the file) leaves `_ManagedRotatingFileHandler`'s open fd pinned to the renamed inode. All subsequent writes go to the rotated backup instead of the file every operator expects to read, producing the symptom 'gateway.log frozen mid-write while agent.log keeps growing with gateway.* records'. PR #16229 fixed the original CLI->gateway init-order bug (#8404) so the handler attaches in the first place. This is the sibling fix for what happens after attach, when something external rotates underneath us. Adds a WatchedFileHandler-style inode check on emit(): if baseFilename no longer matches the open stream's (dev,ino), close the stale fd and reopen at the expected path. doRollover() refreshes the snapshot so our own rollover isn't misidentified as external. Five regression tests cover the matrix: external rename, external unlink, external truncate (must NOT trigger reopen — inode unchanged), normal doRollover() (must still work), and the end-to-end Allen-reproduction (rotate + re-call setup_logging). 55/55 tests in tests/test_hermes_logging.py pass; 5972/5972 in tests/gateway/ pass.
KKT-OPT
pushed a commit
to KKT-OPT/hermes-agent
that referenced
this pull request
May 31, 2026
…sResearch#34349) External rotation (logrotate, manual `mv gateway.log gateway.log.1`, another process rotating the file) leaves `_ManagedRotatingFileHandler`'s open fd pinned to the renamed inode. All subsequent writes go to the rotated backup instead of the file every operator expects to read, producing the symptom 'gateway.log frozen mid-write while agent.log keeps growing with gateway.* records'. PR NousResearch#16229 fixed the original CLI->gateway init-order bug (NousResearch#8404) so the handler attaches in the first place. This is the sibling fix for what happens after attach, when something external rotates underneath us. Adds a WatchedFileHandler-style inode check on emit(): if baseFilename no longer matches the open stream's (dev,ino), close the stale fd and reopen at the expected path. doRollover() refreshes the snapshot so our own rollover isn't misidentified as external. Five regression tests cover the matrix: external rename, external unlink, external truncate (must NOT trigger reopen — inode unchanged), normal doRollover() (must still work), and the end-to-end Allen-reproduction (rotate + re-call setup_logging). 55/55 tests in tests/test_hermes_logging.py pass; 5972/5972 in tests/gateway/ pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes the
gateway.loghandler not being attached when logging is initialized in CLI mode before gateway startup.The normal
hermes gateway runpath initializes logging early through the CLI entrypoint, then callssetup_logging(mode="gateway")later fromgateway/run.py. Before this change, the second call returned immediately when_logging_initializedwas already true, so the gateway-specificgateway.loghandler was never attached.This keeps logging setup idempotent, but allows a later gateway-mode call to attach the missing gateway handler. The existing rotating-handler helper already deduplicates by file path, so repeated gateway setup calls do not add duplicate handlers.
Related Issue
Fixes #8404
Type of Change
Changes Made
hermes_logging.py: move the idempotency return until after the gateway handler attachment path sosetup_logging(mode="gateway")can addgateway.logafter earlier CLI setup.tests/test_hermes_logging.py: add regression coverage for CLI → gateway initialization and repeated gateway setup calls.How to Test
hermes_logging.setup_logging(mode="cli").hermes_logging.setup_logging(mode="gateway").gateway.loghandler exists and receivesgateway.*records.Targeted test:
.venv/bin/python -m pytest tests/test_hermes_logging.py -n 4Result:
50 passed in 0.80sFull suite:
.venv/bin/python -m pytest -n 4Result:
108 failed, 16071 passed, 41 skipped, 210 warnings in 351.86sThe full-suite failures are broad existing repo failures outside this logging change. Examples include API server default port/config expectations, gateway approval/Tirith setup, DingTalk mocked SDK behavior, broad Discord gateway tests, backup/profile restoration, web server schema, tool arg coercion, Tirith marker cleanup, and TUI provider tests. The targeted logging regression file passes.
Checklist
Code
pytest tests/ -qand all tests passDocumentation & Housekeeping
cli-config.yaml.example— N/ACONTRIBUTING.mdorAGENTS.md— N/AScreenshots / Logs
Targeted test output:
50 passed in 0.80sFull-suite output:
108 failed, 16071 passed, 41 skipped, 210 warnings in 351.86s