diff --git a/strix/telemetry/logging.py b/strix/telemetry/logging.py index dad9255b..c8e4bce2 100644 --- a/strix/telemetry/logging.py +++ b/strix/telemetry/logging.py @@ -168,6 +168,17 @@ def attach_preflight_logging(*, debug: bool | None = None) -> None: logging.getLogger(name).setLevel(logging.WARNING) +def remove_preflight_logging() -> None: + """Detach any preflight stderr handler from the tracked logger roots.""" + for name in _TRACKED_ROOTS: + tracked = logging.getLogger(name) + for handler in list(tracked.handlers): + if getattr(handler, _PREFLIGHT_HANDLER_TAG, False): + tracked.removeHandler(handler) + with contextlib.suppress(Exception): + handler.close() + + def setup_scan_logging(run_dir: Path, *, debug: bool | None = None) -> Callable[[], None]: """Attach scan-scoped handlers; return a teardown callable. @@ -185,6 +196,7 @@ def setup_scan_logging(run_dir: Path, *, debug: bool | None = None) -> Callable[ time. Safe to call from a ``finally`` block. """ configure_dependency_logging() + remove_preflight_logging() debug = debug_logging_enabled(debug=debug) diff --git a/tests/test_preflight_logging.py b/tests/test_preflight_logging.py index caee9a84..d4f6ef48 100644 --- a/tests/test_preflight_logging.py +++ b/tests/test_preflight_logging.py @@ -11,20 +11,26 @@ from strix.interface.main import ( _format_connection_error_detail, ) from strix.telemetry import logging as tlog -from strix.telemetry.logging import attach_preflight_logging, debug_logging_enabled +from strix.telemetry.logging import ( + attach_preflight_logging, + debug_logging_enabled, + remove_preflight_logging, + setup_scan_logging, +) if TYPE_CHECKING: + from pathlib import Path + import pytest -def _remove_preflight_handlers() -> None: - for tracked_name in ("strix", "openai.agents"): - tracked = logging.getLogger(tracked_name) - for handler in list(tracked.handlers): - if getattr(handler, tlog._PREFLIGHT_HANDLER_TAG, False): - tracked.removeHandler(handler) - handler.close() +def _preflight_handlers(name: str) -> list[logging.Handler]: + return [ + handler + for handler in logging.getLogger(name).handlers + if getattr(handler, tlog._PREFLIGHT_HANDLER_TAG, False) + ] def test_exception_messages_walks_cause_chain_to_ssl_error() -> None: @@ -77,4 +83,20 @@ def test_attach_preflight_logging_emits_debug_to_stderr( captured = capsys.readouterr() assert "LLM warm-up failed" in captured.err finally: - _remove_preflight_handlers() + remove_preflight_logging() + + +def test_setup_scan_logging_removes_preflight_handler( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + monkeypatch.delenv("STRIX_DEBUG", raising=False) + attach_preflight_logging() + assert _preflight_handlers("strix") + + teardown = setup_scan_logging(tmp_path) + try: + for name in ("strix", "openai.agents"): + assert not _preflight_handlers(name) + finally: + teardown()