diff --git a/tests/test_api_admin.py b/tests/test_api_admin.py index be48a55..c4f242e 100644 --- a/tests/test_api_admin.py +++ b/tests/test_api_admin.py @@ -1867,7 +1867,7 @@ class TestScanReadsVideos(AdminAPITestCase): (self.output_dir / "bad.png").write_bytes(b"\x89PNG not really") GalleryConfig.MONITORING_DIRECTORIES = [self._root(self.output_dir)] - with self.assertLogs(level="WARNING") as cm: + with self.assertLogs("prompt_manager", level="WARNING") as cm: body = await ( await self.client.request("POST", "/prompt_manager/scan") ).text() diff --git a/tests/test_utils_logging_config.py b/tests/test_utils_logging_config.py index b1359f9..3102b08 100644 --- a/tests/test_utils_logging_config.py +++ b/tests/test_utils_logging_config.py @@ -263,5 +263,35 @@ class TestConfiguration(IsolatedLoggerTestCase): self.manager.update_config({"console_logging": False}) +class TestConsoleNoise(IsolatedLoggerTestCase): + """ComfyUI's console only sees warnings unless the level is DEBUG.""" + + def _console_handler(self) -> logging.StreamHandler: + return next( + h + for h in logging.getLogger("prompt_manager").handlers + if type(h) is logging.StreamHandler + ) + + def test_records_do_not_propagate_to_comfyui_root_logger(self) -> None: + self.assertFalse(logging.getLogger("prompt_manager").propagate) + + def test_console_hides_info_at_the_default_level(self) -> None: + self.manager.update_config({"console_logging": True}) + self.assertEqual(self._console_handler().level, logging.WARNING) + self.logger.info("startup chatter") + self.assertEqual(self.manager.get_recent_logs(limit=1)[0]["level"], "INFO") + log_file = pathlib.Path(self.log_dir) / "prompt_manager.log" + self.assertIn("startup chatter", log_file.read_text()) + self.manager.update_config({"console_logging": False}) + + def test_debug_level_opens_the_console(self) -> None: + self.manager.update_config({"console_logging": True, "level": "DEBUG"}) + self.assertEqual(self._console_handler().level, logging.DEBUG) + self.manager.update_config({"level": "INFO"}) + self.assertEqual(self._console_handler().level, logging.WARNING) + self.manager.update_config({"console_logging": False}) + + if __name__ == "__main__": unittest.main() diff --git a/utils/logging_config.py b/utils/logging_config.py index e4aa69c..b741eaf 100644 --- a/utils/logging_config.py +++ b/utils/logging_config.py @@ -85,6 +85,8 @@ class PromptManagerLogger: # Main logger self.logger = logging.getLogger("prompt_manager") self.logger.setLevel(getattr(logging, self.config["level"])) + # ComfyUI's root handler would print every record a second time. + self.logger.propagate = False # Clear existing handlers for handler in self.logger.handlers[:]: @@ -100,6 +102,7 @@ class PromptManagerLogger: # Console handler if self.config["console_logging"]: console_handler = logging.StreamHandler() + console_handler.setLevel(self._console_level()) console_handler.setFormatter(formatter) self.logger.addHandler(console_handler) @@ -124,6 +127,15 @@ class PromptManagerLogger: # Component-specific loggers self._setup_component_loggers() + def _console_level(self) -> int: + """Console threshold: everything at DEBUG, otherwise warnings only. + + INFO still reaches the log file and the web log viewer. + """ + if str(self.config["level"]).upper() == "DEBUG": + return logging.DEBUG + return logging.WARNING + def _setup_component_loggers(self): """Set up loggers for specific components. @@ -363,6 +375,10 @@ class PromptManagerLogger: logger = logging.getLogger(logger_name) logger.setLevel(level) + for handler in self.logger.handlers: + if type(handler) is logging.StreamHandler: + handler.setLevel(self._console_level()) + # Re-setup loggers if handlers changed if any( key in new_config