feat: add TUI-safe logging mode that disables RichHandler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,21 @@ def setup_logging(
|
||||
)
|
||||
|
||||
|
||||
def setup_logging_for_tui() -> None:
|
||||
"""Reconfigure logging for Textual TUI mode.
|
||||
|
||||
Removes the RichHandler (which writes to stdout and corrupts the TUI)
|
||||
while preserving any file handlers. Call this from the Textual App's
|
||||
on_mount() before any agent work begins.
|
||||
"""
|
||||
from rich.logging import RichHandler
|
||||
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.handlers = [
|
||||
h for h in root_logger.handlers if not isinstance(h, RichHandler)
|
||||
]
|
||||
|
||||
|
||||
def get_logger(name: str) -> structlog.stdlib.BoundLogger:
|
||||
"""Get a named structlog logger.
|
||||
|
||||
|
||||
31
tests/unit/test_logging_tui.py
Normal file
31
tests/unit/test_logging_tui.py
Normal file
@@ -0,0 +1,31 @@
|
||||
"""Tests for TUI-safe logging configuration."""
|
||||
|
||||
import logging
|
||||
|
||||
from app.utils.logging import setup_logging, setup_logging_for_tui
|
||||
|
||||
|
||||
class TestTuiLogging:
|
||||
def test_setup_logging_for_tui_removes_rich_handler(self) -> None:
|
||||
"""TUI mode should have no RichHandler on root logger."""
|
||||
from rich.logging import RichHandler
|
||||
|
||||
# First set up normal logging (adds RichHandler)
|
||||
setup_logging()
|
||||
root = logging.getLogger()
|
||||
assert any(isinstance(h, RichHandler) for h in root.handlers)
|
||||
|
||||
# Switch to TUI mode
|
||||
setup_logging_for_tui()
|
||||
root = logging.getLogger()
|
||||
assert not any(isinstance(h, RichHandler) for h in root.handlers)
|
||||
|
||||
def test_setup_logging_for_tui_keeps_file_handler(self, tmp_path) -> None:
|
||||
"""TUI mode should preserve file handler if configured."""
|
||||
log_file = tmp_path / "test.log"
|
||||
setup_logging(log_file=log_file)
|
||||
setup_logging_for_tui()
|
||||
|
||||
root = logging.getLogger()
|
||||
file_handlers = [h for h in root.handlers if isinstance(h, logging.FileHandler)]
|
||||
assert len(file_handlers) == 1
|
||||
Reference in New Issue
Block a user