fix: route component log files added after profile routing is already on

Adoption of a second home only wrapped the file handlers that existed at
adoption time. A later setup_logging(hermes_home=<known>, mode="gateway")
skipped _adopt_secondary_home (the home is already served) and appended a
bare _ManagedRotatingFileHandler for gateway.log, which carries no home
filter and so took every profile's gateway records. When a router is
already queued, the new handler is now wrapped in a _ProfileRoutingFileHandler
over the union of the live routers' homes.

Review finding: setup_logging(A); setup_logging(B); setup_logging(A, mode="gateway") wrote gw-b into A's gateway.log.
This commit is contained in:
teknium1
2026-09-14 21:18:07 -07:00
committed by Teknium
parent c7a942e833
commit f8eb2912ce
2 changed files with 35 additions and 0 deletions
+11
View File
@@ -669,6 +669,17 @@ def _add_rotating_handler(
)
if log_filter is not None:
handler.addFilter(log_filter)
# Routing already on (a second home adopted earlier): a component log added now —
# ``mode="gateway"`` after the fact — must route too, or it takes every home's records.
routers = [h for h in _queued_file_handlers if isinstance(h, _ProfileRoutingFileHandler)]
if routers:
homes: set[Path] = set()
for router in routers:
homes.add(router._default_home)
homes.update(router._profile_homes)
routed = _ProfileRoutingFileHandler(handler, sorted(homes))
_quietly(handler.close)
handler = routed
# Queue, not ``addHandler``: the rotation-lock wait never runs on the caller's thread.
_register_queued_handler(handler)
+24
View File
@@ -196,6 +196,30 @@ class TestSetupLogging:
assert (profile_home / "logs" / "agent.log").read_text().count("once please") == 1
assert "once please" not in (hermes_home / "logs" / "agent.log").read_text()
def test_a_component_log_added_after_routing_is_routed_too(self, hermes_home, tmp_path):
"""setup_logging(mode="gateway") for an already-known home AFTER a second home turned
routing on: gateway.log must be a routed writer, not a bare handler taking every home."""
from hermes_constants import reset_hermes_home_override, set_hermes_home_override
profile_home = tmp_path / "profile-b"
profile_home.mkdir()
hermes_logging.setup_logging(hermes_home=hermes_home)
hermes_logging.setup_logging(hermes_home=profile_home)
hermes_logging.setup_logging(hermes_home=hermes_home, mode="gateway")
logger = logging.getLogger("gateway.run.routed-component-test")
token = set_hermes_home_override(profile_home)
try:
logger.info("gw-b")
finally:
reset_hermes_home_override(token)
logger.info("gw-a")
hermes_logging.flush_log_queue()
a_log = (hermes_home / "logs" / "gateway.log").read_text()
assert "gw-a" in a_log and "gw-b" not in a_log
assert "gw-b" in (profile_home / "logs" / "gateway.log").read_text()