diff --git a/carbontracker/loggerutil.py b/carbontracker/loggerutil.py index 4b20624..00adfab 100644 --- a/carbontracker/loggerutil.py +++ b/carbontracker/loggerutil.py @@ -58,23 +58,23 @@ def filter(self, record): class Logger: - def __init__(self, log_dir=None, verbose=0, log_prefix=""): + def __init__(self, log_dir=None, verbose=0, log_prefix="", logger_id="root"): self.verbose = verbose self.logger, self.logger_output, self.logger_err = self._setup( - log_dir=log_dir, log_prefix=log_prefix + log_dir=log_dir, log_prefix=log_prefix, logger_id=logger_id ) self._log_initial_info() self.msg_prepend = "CarbonTracker: " - def _setup(self, log_dir=None, log_prefix=""): + def _setup(self, log_dir=None, log_prefix="", logger_id="root"): if log_prefix: log_prefix += "_" - logger_name = f"{log_prefix}{os.getpid()}" + logger_name = f"{log_prefix}{os.getpid()}.{logger_id}" logger = logging.getLogger(logger_name) - logger_err = logging.getLogger("carbontracker.err") - logger_output = logging.getLogger("carbontracker.output") + logger_err = logging.getLogger(f"carbontracker.{logger_id}.err") + logger_output = logging.getLogger(f"carbontracker.{logger_id}.output") logger.propagate = False logger.setLevel(logging.DEBUG) logger_output.propagate = False diff --git a/carbontracker/tracker.py b/carbontracker/tracker.py index ac6bc0c..ad6887e 100644 --- a/carbontracker/tracker.py +++ b/carbontracker/tracker.py @@ -8,6 +8,7 @@ from typing import List, Union import numpy as np +from random import randint from carbontracker import constants from carbontracker import loggerutil @@ -331,7 +332,10 @@ def __init__( try: pids = self._get_pids() self.logger = loggerutil.Logger( - log_dir=log_dir, verbose=verbose, log_prefix=log_file_prefix + log_dir=log_dir, + verbose=verbose, + log_prefix=log_file_prefix, + logger_id=str(randint(1, 999999)), ) self.tracker = CarbonTrackerThread( delete=self._delete, diff --git a/tests/test_loggerutil.py b/tests/test_loggerutil.py index cbee1a2..4a658ff 100644 --- a/tests/test_loggerutil.py +++ b/tests/test_loggerutil.py @@ -3,7 +3,7 @@ from carbontracker import loggerutil from carbontracker.loggerutil import Logger, convert_to_timestring import unittest.mock -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch import tempfile import os import logging @@ -164,6 +164,13 @@ def test_output(self, mock_info): mock_info.assert_called_once_with(f"CarbonTracker: {test_message}") + def test_multiple_loggers(self): + logger1 = loggerutil.Logger(logger_id="1") + logger2 = loggerutil.Logger(logger_id="2") + self.assertNotEqual(logger1.logger, logger2.logger) + self.assertNotEqual(logger1.logger_output, logger2.logger_output) + self.assertNotEqual(logger1.logger_err, logger2.logger_err) + if __name__ == "__main__": unittest.main() diff --git a/tests/test_tracker.py b/tests/test_tracker.py index 8f585cf..22bb005 100644 --- a/tests/test_tracker.py +++ b/tests/test_tracker.py @@ -778,6 +778,57 @@ def test_exception_handling( str(context.exception), "'CarbonTracker' object has no attribute 'logger'" ) + # # Instantiating a second instance should not make this instance log twice + # @mock.patch("carbontracker.tracker.CarbonIntensityThread") + # def test_multiple_instances(self, mock_intensity_thread): + # assert self.mock_logger is not None + # assert self.tracker is not None + + # tracker2 = CarbonTracker( + # epochs=5, + # epochs_before_pred=1, + # monitor_epochs=3, + # update_interval=10, + # interpretable=True, + # stop_and_confirm=True, + # ignore_errors=False, + # components="all", + # devices_by_pid=False, + # log_dir=None, + # log_file_prefix="", + # verbose=1, + # decimal_precision=6, + # ) + + # predictor = MagicMock() + # predictor.predict_energy = MagicMock(return_value=100) + # predictor.predict_time = MagicMock(return_value=1000) + + # self.tracker.epochs = 5 + # self.tracker.tracker.total_energy_per_epoch = MagicMock( + # return_value=[10, 20, 30] + # ) + # self.tracker.tracker.epoch_times = [100, 200, 300] + # self.tracker._co2eq = MagicMock(return_value=150) + # self.tracker.interpretable = True + + # self.tracker._output_pred() + + # expected_description = "Predicted consumption for 5 epoch(s):" + + # expected_output = ( + # f"\n{expected_description}\n" + # "\tTime:\t0:16:40\n" + # "\tEnergy:\t100.000000 kWh\n" + # "\tCO2eq:\t150.000000 g" + # "\n\tThis is equivalent to:\n" + # "\t1.395349 km travelled by car" + # ) + + # self.mock_logger.output.assert_called_once_with( + # expected_output, verbose_level=1 + # ) + if __name__ == "__main__": unittest.main()