From 80f673ee9fad3e94936761eec18158521e8c0b44 Mon Sep 17 00:00:00 2001 From: David Ormrod Morley Date: Mon, 2 Dec 2024 12:31:34 +0100 Subject: [PATCH] Logger no longer errors when logfile path is invalid SCMSUITE-9740 SO107 --- core/logging.py | 13 ++++++++++--- unit_tests/test_logging.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/core/logging.py b/core/logging.py index dc0f5404..58ceadba 100644 --- a/core/logging.py +++ b/core/logging.py @@ -111,6 +111,9 @@ def _configure_file_handler(self, level: int, logfile_path: Optional[str]): """ # Remove and close existing file handler if present and required + logfile_path = ( + os.path.abspath(logfile_path) if logfile_path is not None else None + ) # convert any relative paths to abs paths if self._file_handler is not None and (logfile_path is None or logfile_path != self._file_handler.baseFilename): self._remove_handler(self._file_handler) self._file_handler = None @@ -124,9 +127,13 @@ def _configure_file_handler(self, level: int, logfile_path: Optional[str]): if logger._file_handler is not None and logger._file_handler.baseFilename == logfile_path: raise FileError(f"Logger '{name}' already exists with logfile path '{logfile_path}'") - self._file_handler = logging.FileHandler(logfile_path) - self._file_handler.setFormatter(self._file_formatter) - self._logger.addHandler(self._file_handler) + try: + self._file_handler = logging.FileHandler(logfile_path) + self._file_handler.setFormatter(self._file_formatter) + self._logger.addHandler(self._file_handler) + except FileNotFoundError: + # Logger should not error if logfile directory does not exist + pass # Update the logfile handler level if required if self._file_handler is not None: diff --git a/unit_tests/test_logging.py b/unit_tests/test_logging.py index 54258770..9329f45a 100644 --- a/unit_tests/test_logging.py +++ b/unit_tests/test_logging.py @@ -83,6 +83,34 @@ def test_configure_writes_to_logfile_up_to_and_including_level(self): ) logger.close() + def test_configure_does_not_error_with_invalid_logfile_location(self): + log_file = "not/a/file" + logger = get_logger(str(uuid.uuid4())) + logger.configure(logfile_path=log_file, logfile_level=3) + logger.log("log line", 3) + + logger.close() + + def test_configure_only_updates_logfile_handler_when_abspath_changes(self): + with temp_file_path(suffix=".log") as temp_log_file1: + with temp_file_path(suffix=".log") as temp_log_file2: + rel_path1 = temp_log_file1.split("/")[-1] + rel_path2 = temp_log_file2.split("/")[-1] + + logger = get_logger(str(uuid.uuid4())) + logger.configure(logfile_path=rel_path1, logfile_level=3) + fh1 = logger._file_handler + logger.configure(logfile_path=rel_path1, logfile_level=3) + fh2 = logger._file_handler + logger.configure(logfile_path=rel_path2, logfile_level=3) + fh3 = logger._file_handler + logger.configure(logfile_path=rel_path2, logfile_level=3) + fh4 = logger._file_handler + + assert fh1 == fh2 != fh3 == fh4 + + logger.close() + def test_close_removes_stdout_and_logfile_handlers(self): with patch("sys.stdout", new_callable=StringIO) as mock_stdout: with temp_file_path(suffix=".log") as temp_log_file: