Skip to content

Commit

Permalink
Merge pull request #73 from Snailed/fix-multiple-instantiations
Browse files Browse the repository at this point in the history
Fix logging redudancy on multiple instances
  • Loading branch information
Snailed authored Jul 23, 2024
2 parents e404bdc + 3c50ae2 commit 050cc45
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 8 deletions.
12 changes: 6 additions & 6 deletions carbontracker/loggerutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion carbontracker/tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
9 changes: 8 additions & 1 deletion tests/test_loggerutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
51 changes: 51 additions & 0 deletions tests/test_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 050cc45

Please sign in to comment.