diff --git a/data_safe_haven/logging/plain_file_handler.py b/data_safe_haven/logging/plain_file_handler.py index c41d0e5ffc..ffce4a551c 100644 --- a/data_safe_haven/logging/plain_file_handler.py +++ b/data_safe_haven/logging/plain_file_handler.py @@ -16,16 +16,23 @@ def __init__(self, *args: Any, **kwargs: Any): super().__init__(*args, **kwargs) @staticmethod - def strip_formatting(input_string: str) -> str: + def strip_rich_formatting(input_string: str) -> str: """Strip console markup formatting from a string""" text = Text.from_markup(input_string) text.spans = [] return str(text) + @staticmethod + def strip_ansi_escapes(input_string: str) -> str: + """Strip ANSI escape sequences from a string""" + text = Text.from_ansi(input_string) + text.spans = [] + return str(text) + def emit(self, record: logging.LogRecord) -> None: """Emit a record without formatting""" if isinstance(record.msg, Text): # Convert rich.text.Text objects to strings record.msg = str(record.msg) - record.msg = self.strip_formatting(record.msg) + record.msg = self.strip_ansi_escapes(self.strip_rich_formatting(record.msg)) super().emit(record) diff --git a/tests/logging/test_plain_file_handler.py b/tests/logging/test_plain_file_handler.py index a2bf60ad81..90f7c6ca70 100644 --- a/tests/logging/test_plain_file_handler.py +++ b/tests/logging/test_plain_file_handler.py @@ -1,6 +1,15 @@ +import pytest + from data_safe_haven.logging.plain_file_handler import PlainFileHandler class TestPlainFileHandler: - def test_strip_formatting(self): - assert PlainFileHandler.strip_formatting("[green]hello[/]") == "hello" + def test_strip_rich_formatting(self): + assert PlainFileHandler.strip_rich_formatting("[green]Hello[/]") == "Hello" + + @pytest.mark.parametrize("escape", ["\033", "\x1B", "\u001b", "\x1B"]) + def test_strip_ansi_escapes(self, escape): + assert ( + PlainFileHandler.strip_ansi_escapes(f"{escape}[31;1;4mHello{escape}[0m") + == "Hello" + )