Skip to content

Commit

Permalink
Merge pull request #101 from small-thinking/fix-logger-4
Browse files Browse the repository at this point in the history
Fix logger
  • Loading branch information
yxjiang authored Jul 23, 2024
2 parents 167d519 + cf02058 commit 2303650
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 17 deletions.
11 changes: 9 additions & 2 deletions polymind/core/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

class Logger:
_instance = None
_initialized = False

class LoggingLevel(Enum):
DEBUG = logging.DEBUG
Expand Down Expand Up @@ -39,6 +40,9 @@ def __init__(
verbose: bool = True,
display_level: Optional[Union[LoggingLevel, str]] = None,
):
if self._initialized:
return

load_dotenv(override=True)

if display_level is None:
Expand All @@ -52,8 +56,9 @@ def __init__(
self.logger = logging.getLogger(logger_name)
self.logger.setLevel(self.logging_level.value)

if self.logger.hasHandlers():
self.logger.handlers.clear()
# Remove all existing handlers
for handler in self.logger.handlers:
self.logger.removeHandler(handler)

self.formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s (%(filename)s:%(lineno)d)")
self.console_handler = logging.StreamHandler()
Expand All @@ -66,6 +71,8 @@ def __init__(
logging.addLevelName(self.LoggingLevel.TASK.value, "TASK")
logging.addLevelName(self.LoggingLevel.THOUGHT_PROCESS.value, "THOUGHT_PROCESS")

self._initialized = True

def _log(self, message: str, level: LoggingLevel, color: str) -> None:
if level.value >= self.logging_level.value:
if len(inspect.stack()) >= 4:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "polymind"
version = "0.0.59" # Update this version before publishing to PyPI
version = "0.0.60" # Update this version before publishing to PyPI
description = "PolyMind is a customizable collaborative multi-agent framework for collective intelligence and distributed problem solving."
authors = ["TechTao"]
license = "MIT License"
Expand Down
37 changes: 23 additions & 14 deletions tests/polymind/core/test_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,31 @@ class TestLogger:

@pytest.fixture(scope="function")
def setup_logger(self, tmp_path):
# Reset the Logger singleton for each test
Logger._instance = None
Logger._initialized = False

log_folder = tmp_path / "logs"
log_folder.mkdir()
logger = Logger(logger_name="test_logger", display_level="DEBUG") # Change to DEBUG
logger = Logger(logger_name="test_logger", display_level="DEBUG")
return logger

def test_initialization(self, setup_logger):
logger = setup_logger
assert logger.logging_level == Logger.LoggingLevel.DEBUG
assert logger.logger.level == Logger.LoggingLevel.DEBUG.value
assert len(logger.logger.handlers) == 1
assert logger._initialized == True

def test_single_initialization(self):
logger1 = Logger(logger_name="test_logger1", display_level="DEBUG")
logger2 = Logger(logger_name="test_logger2", display_level="INFO")

assert logger1 is logger2, "Logger is not implementing the singleton pattern correctly"
assert (
logger.logging_level == Logger.LoggingLevel.DEBUG
), f"Logger level is incorrect: {logger.logging_level} != DEBUG"
assert (
logger.logger.level == Logger.LoggingLevel.DEBUG.value
), f"Logger level is not set correctly: {logger.logger.level} != {Logger.LoggingLevel.DEBUG.value}"
assert len(logger.logger.handlers) == 1, "Logger handlers are not initialized properly"
logger1.logging_level == Logger.LoggingLevel.DEBUG
), "Logger level should not change after first initialization"
assert len(logger1.logger.handlers) == 1, "Only one handler should be added"

@pytest.mark.parametrize(
"log_method, log_level, color, expected_log_method",
Expand Down Expand Up @@ -84,19 +95,17 @@ def test_from_string_method(self):
with pytest.raises(ValueError):
Logger.LoggingLevel.from_string("INVALID_LEVEL")

def test_logger_singleton(self):
logger1 = Logger(logger_name="test_logger1")
logger2 = Logger(logger_name="test_logger2")
assert logger1 is logger2, "Logger is not implementing the singleton pattern correctly"

@patch("logging.getLogger")
def test_custom_log_levels_added(self, mock_get_logger):
@patch("logging.StreamHandler")
def test_custom_log_levels_added(self, mock_stream_handler, mock_get_logger):
mock_logger = MagicMock()
mock_get_logger.return_value = mock_logger

mock_handler = MagicMock()
mock_stream_handler.return_value = mock_handler

Logger(logger_name="test_logger")

mock_logger.addHandler.assert_called()
assert logging.getLevelName(25) == "TOOL", "TOOL log level not added"
assert logging.getLevelName(26) == "TASK", "TASK log level not added"
assert logging.getLevelName(27) == "THOUGHT_PROCESS", "THOUGHT_PROCESS log level not added"

0 comments on commit 2303650

Please sign in to comment.