diff --git a/src/corelibs/logging_handling/log.py b/src/corelibs/logging_handling/log.py index b2f20cb..15bdea5 100644 --- a/src/corelibs/logging_handling/log.py +++ b/src/corelibs/logging_handling/log.py @@ -32,6 +32,7 @@ class ConsoleFormat(Flag): FILE = auto() FUNCTION = auto() LINENO = auto() + LEVEL = auto() class ConsoleFormatSettings: @@ -43,14 +44,17 @@ class ConsoleFormatSettings: ConsoleFormat.NAME | ConsoleFormat.FILE | ConsoleFormat.FUNCTION | - ConsoleFormat.LINENO + ConsoleFormat.LINENO | + ConsoleFormat.LEVEL ) - # show time with no time zone, file and line - CONDENSED = ConsoleFormat.TIME | ConsoleFormat.FILE | ConsoleFormat.LINENO - # only time - MINIMAL = ConsoleFormat.TIME + # show time with no time zone, file, line and level + CONDENSED = ConsoleFormat.TIME | ConsoleFormat.FILE | ConsoleFormat.LINENO | ConsoleFormat.LEVEL + # only time and level + MINIMAL = ConsoleFormat.TIME | ConsoleFormat.LEVEL + # only level + BARE = ConsoleFormat.LEVEL # only message - BARE = ConsoleFormat(0) + NONE = ConsoleFormat(0) @staticmethod def from_string(setting_str: str, default: ConsoleFormat | None = None) -> ConsoleFormat | None: @@ -655,8 +659,11 @@ class Log(LogParent): set_group.append('%(lineno)d') format_string += ':'.join(set_group) format_string += '] ' - # always level + message - format_string += '<%(levelname)s> %(message)s' + # level if wanted + if ConsoleFormat.LEVEL in console_format_type: + format_string += '<%(levelname)s> ' + # always message + format_string += '%(message)s' return format_string def __set_time_format_for_console_formatter( diff --git a/test-run/logging_handling/log.py b/test-run/logging_handling/log.py index e1d0dc1..2a11213 100644 --- a/test-run/logging_handling/log.py +++ b/test-run/logging_handling/log.py @@ -25,11 +25,13 @@ def main(): "log_level_file": 'DEBUG', # "console_color_output_enabled": False, "per_run_log": True, - # "console_format_type": ConsoleFormatSettings.BARE, + # "console_format_type": ConsoleFormatSettings.NONE, # "console_format_type": ConsoleFormatSettings.MINIMAL, - "console_format_type": ConsoleFormat.TIME_MICROSECONDS | ConsoleFormat.NAME, + "console_format_type": ConsoleFormat.TIME_MICROSECONDS | ConsoleFormat.NAME | ConsoleFormat.LEVEL, # "console_format_type": ConsoleFormat.NAME, - # "console_format_type": ConsoleFormat.TIME | ConsoleFormat.TIMEZONE | ConsoleFormat.LINENO, + # "console_format_type": ( + # ConsoleFormat.TIME | ConsoleFormat.TIMEZONE | ConsoleFormat.LINENO | ConsoleFormat.LEVEL + # ), } ) logn = Logger(log.get_logger_settings()) diff --git a/tests/unit/logging_handling/log_testing/test_log_1_settings_parsing_spacers_parameters.py b/tests/unit/logging_handling/log_testing/test_log_1_settings_parsing_spacers_parameters.py index 60b4002..cd3e1f2 100644 --- a/tests/unit/logging_handling/log_testing/test_log_1_settings_parsing_spacers_parameters.py +++ b/tests/unit/logging_handling/log_testing/test_log_1_settings_parsing_spacers_parameters.py @@ -153,6 +153,19 @@ class TestLogSettingsParsing: assert log.log_settings["console_format_type"] == ConsoleFormatSettings.BARE + def test_parse_console_format_type_none(self, tmp_log_path: Path): + """Test parsing with console_format_type set to NONE""" + settings: dict[str, Any] = { + "console_format_type": ConsoleFormatSettings.NONE, + } + log = Log( + log_path=tmp_log_path, + log_name="test", + log_settings=settings # type: ignore + ) + + assert log.log_settings["console_format_type"] == ConsoleFormatSettings.NONE + def test_parse_console_format_type_invalid(self, tmp_log_path: Path): """Test parsing with invalid console_format_type raises TypeError""" settings: dict[str, Any] = { @@ -207,6 +220,11 @@ class TestConsoleFormatSettingsFromString: result = ConsoleFormatSettings.from_string('BARE') assert result == ConsoleFormatSettings.BARE + def test_from_string_none(self): + """Test from_string with 'NONE' returns correct format""" + result = ConsoleFormatSettings.from_string('NONE') + assert result == ConsoleFormatSettings.NONE + def test_from_string_invalid_returns_none(self): """Test from_string with invalid string returns None""" result = ConsoleFormatSettings.from_string('INVALID') @@ -234,6 +252,7 @@ class TestConsoleFormatSettingsFromString: ("CONDENSED", ConsoleFormatSettings.CONDENSED), ("MINIMAL", ConsoleFormatSettings.MINIMAL), ("BARE", ConsoleFormatSettings.BARE), + ("NONE", ConsoleFormatSettings.NONE), ]) def test_from_string_all_valid_settings(self, setting_name: str, expected: Any): """Test from_string with all valid setting names""" diff --git a/tests/unit/logging_handling/log_testing/test_log_3_custom_console_formatter.py b/tests/unit/logging_handling/log_testing/test_log_3_custom_console_formatter.py index 18b3bca..cd68375 100644 --- a/tests/unit/logging_handling/log_testing/test_log_3_custom_console_formatter.py +++ b/tests/unit/logging_handling/log_testing/test_log_3_custom_console_formatter.py @@ -178,6 +178,17 @@ class TestUpdateConsoleFormatter: # Verify formatter was updated assert formatter is not None + def test_update_console_formatter_to_none(self, log_instance: Log): + """Test updating console formatter to NONE format""" + log_instance.update_console_formatter(ConsoleFormatSettings.NONE) + + # Get the console handler's formatter + console_handler = log_instance.handlers[log_instance.CONSOLE_HANDLER] + formatter = console_handler.formatter + + # Verify formatter was updated + assert formatter is not None + def test_update_console_formatter_to_all(self, log_instance: Log): """Test updating console formatter to ALL format""" log_instance.update_console_formatter(ConsoleFormatSettings.ALL) @@ -283,4 +294,18 @@ class TestUpdateConsoleFormatter: # Verify message was logged assert "Test warning message" in caplog.text + def test_update_console_formatter_none_format_output( + self, log_instance: Log, caplog: pytest.LogCaptureFixture + ): + """Test that NONE formatter outputs only the message without any formatting""" + # Set to NONE format (message only, no level indicator) + log_instance.update_console_formatter(ConsoleFormatSettings.NONE) + + # Configure caplog to capture at the appropriate level + with caplog.at_level(logging.WARNING): + log_instance.warning("Test warning message") + + # Verify message was logged + assert "Test warning message" in caplog.text + # __END__ diff --git a/tests/unit/logging_handling/log_testing/test_log_5_handler_management.py b/tests/unit/logging_handling/log_testing/test_log_5_handler_management.py index bde8652..c97cdce 100644 --- a/tests/unit/logging_handling/log_testing/test_log_5_handler_management.py +++ b/tests/unit/logging_handling/log_testing/test_log_5_handler_management.py @@ -12,6 +12,7 @@ from corelibs.logging_handling.log import ( LogParent, LogSettings, ConsoleFormatSettings, + ConsoleFormat, ) from corelibs.logging_handling.logging_level_handling.logging_level import LoggingLevel @@ -108,4 +109,101 @@ class TestHandlerManagement: result2 = log.add_handler("test", handler2) assert result2 is False + def test_change_console_format_to_minimal(self, log_instance: Log): + """Test changing console handler format to MINIMAL""" + original_formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + + log_instance.update_console_formatter(ConsoleFormatSettings.MINIMAL) + + new_formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + assert new_formatter is not original_formatter + assert new_formatter is not None + + def test_change_console_format_to_condensed(self, log_instance: Log): + """Test changing console handler format to CONDENSED""" + log_instance.update_console_formatter(ConsoleFormatSettings.CONDENSED) + + formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + assert formatter is not None + + def test_change_console_format_to_bare(self, log_instance: Log): + """Test changing console handler format to BARE""" + log_instance.update_console_formatter(ConsoleFormatSettings.BARE) + + formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + assert formatter is not None + + def test_change_console_format_to_none(self, log_instance: Log): + """Test changing console handler format to NONE""" + log_instance.update_console_formatter(ConsoleFormatSettings.NONE) + + formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + assert formatter is not None + + def test_change_console_format_to_all(self, log_instance: Log): + """Test changing console handler format to ALL""" + # Start with a different format + log_instance.update_console_formatter(ConsoleFormatSettings.MINIMAL) + + log_instance.update_console_formatter(ConsoleFormatSettings.ALL) + + formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + assert formatter is not None + + def test_change_console_format_multiple_times(self, log_instance: Log): + """Test changing console handler format multiple times""" + formatters: list[logging.Formatter | None] = [] + + for format_type in [ + ConsoleFormatSettings.MINIMAL, + ConsoleFormatSettings.CONDENSED, + ConsoleFormatSettings.BARE, + ConsoleFormatSettings.NONE, + ConsoleFormatSettings.ALL, + ]: + log_instance.update_console_formatter(format_type) + formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + formatters.append(formatter) + assert formatter is not None + + # Verify each formatter is unique (new instance each time) + for i, formatter in enumerate(formatters): + for j, other_formatter in enumerate(formatters): + if i != j: + assert formatter is not other_formatter + + def test_change_console_format_with_disabled_console( + self, tmp_log_path: Path, basic_log_settings: LogSettings + ): + """Test changing console format when console is disabled does nothing""" + basic_log_settings['console_enabled'] = False + log = Log( + log_path=tmp_log_path, + log_name="test_log", + log_settings=basic_log_settings + ) + + # Should not raise error, just return early + log.update_console_formatter(ConsoleFormatSettings.MINIMAL) + + # Console handler should not exist + assert log.CONSOLE_HANDLER not in log.handlers + + @pytest.mark.parametrize("format_type", [ + ConsoleFormatSettings.ALL, + ConsoleFormatSettings.CONDENSED, + ConsoleFormatSettings.MINIMAL, + ConsoleFormatSettings.BARE, + ConsoleFormatSettings.NONE, + ]) + def test_change_console_format_parametrized( + self, log_instance: Log, format_type: ConsoleFormat # type: ignore + ): + """Test changing console format with all format types""" + log_instance.update_console_formatter(format_type) + + formatter = log_instance.handlers[log_instance.CONSOLE_HANDLER].formatter + assert formatter is not None + assert isinstance(formatter, logging.Formatter) + # __END__