diff --git a/codecarbon/emissions_tracker.py b/codecarbon/emissions_tracker.py index 02e905cca..8a68f9cbe 100644 --- a/codecarbon/emissions_tracker.py +++ b/codecarbon/emissions_tracker.py @@ -639,7 +639,15 @@ def _init_output_methods(self, *, api_key: str = None): ) if OutputMethod.LOGGER in methods: - self._output_handlers.append(self._logging_logger) + if self._logging_logger is None: + logger.warning( + "OutputMethod.LOGGER was requested but no `logging_logger`" + " was provided, so the logger output is skipped. Pass" + " `logging_logger=LoggerOutput(...)` to EmissionsTracker" + " to enable it." + ) + else: + self._output_handlers.append(self._logging_logger) if self._emissions_endpoint: self._output_handlers.append(HTTPOutput(self._emissions_endpoint)) diff --git a/tests/test_emissions_tracker.py b/tests/test_emissions_tracker.py index fd0590a23..71b656c11 100644 --- a/tests/test_emissions_tracker.py +++ b/tests/test_emissions_tracker.py @@ -1,3 +1,4 @@ +import logging import os import shutil import sys @@ -20,6 +21,7 @@ ) from codecarbon.external.geography import CloudMetadata from codecarbon.output import BoAmpsOutput, CodeCarbonAPIOutput, OutputMethod +from codecarbon.output_methods.logger import LoggerOutput from tests.fake_modules import pynvml as fake_pynvml from tests.testdata import ( GEO_METADATA_CANADA, @@ -1099,6 +1101,45 @@ def test_scheduler_warning_shown_when_running( scheduler_warning_found, "Expected scheduler warning was not found" ) + @mock.patch("codecarbon.emissions_tracker.logger") + def test_logger_output_warns_and_skips_without_logging_logger( + self, + mock_logger, + mock_cli_setup, + mock_log_values, + mocked_get_gpu_details, + mocked_env_cloud_details, + mocked_get_gpu_utilization_list, + mocked_is_gpu_details_available, + mocked_is_nvidia_system, + ): + tracker = EmissionsTracker( + project_name=self.project_name, + output_methods=["logger"], + ) + + self.assertNotIn(None, tracker._output_handlers) + warnings = [str(c.args[0]) for c in mock_logger.warning.call_args_list] + self.assertTrue(any("logging_logger" in w for w in warnings)) + + def test_logger_output_succeeds_with_logging_logger( + self, + mock_cli_setup, + mock_log_values, + mocked_get_gpu_details, + mocked_env_cloud_details, + mocked_get_gpu_utilization_list, + mocked_is_gpu_details_available, + mocked_is_nvidia_system, + ): + my_logger = logging.getLogger("test_logger_output") + tracker = EmissionsTracker( + project_name=self.project_name, + output_methods=["logger"], + logging_logger=LoggerOutput(my_logger), + ) + self.assertIsNotNone(tracker) + def test_get_detected_hardware( self, mock_cli_setup,