diff --git a/redisvl/utils/log.py b/redisvl/utils/log.py index 41d5fcb1..a71f33e2 100644 --- a/redisvl/utils/log.py +++ b/redisvl/utils/log.py @@ -3,7 +3,6 @@ import coloredlogs -# constants for logging coloredlogs.DEFAULT_DATE_FORMAT = "%H:%M:%S" coloredlogs.DEFAULT_LOG_FORMAT = "%(asctime)s %(name)s %(levelname)s %(message)s" @@ -15,5 +14,16 @@ def get_logger(name, log_level="info", fmt=None): name = "RedisVL" if log_level == "debug" else name logger = logging.getLogger(name) - coloredlogs.install(level=log_level, logger=logger, fmt=fmt, stream=sys.stdout) + + # Only configure this specific logger, not the root logger + # Check if the logger already has handlers to respect existing configuration + if not logger.handlers: + coloredlogs.install( + level=log_level, + logger=logger, # Pass the specific logger + fmt=fmt, + stream=sys.stdout, + isatty=True, # Only use colors when supported + reconfigure=False, # Don't reconfigure existing loggers + ) return logger diff --git a/tests/unit/logger_interference_checker.py b/tests/unit/logger_interference_checker.py new file mode 100644 index 00000000..7d1c9ca9 --- /dev/null +++ b/tests/unit/logger_interference_checker.py @@ -0,0 +1,25 @@ +import logging +import sys + +# Set up custom logging +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter( + logging.Formatter( + "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)s] %(message)s" + ) +) + +# Configure root logger +root_logger = logging.getLogger() +root_logger.handlers = [handler] +root_logger.setLevel(logging.INFO) + +# Log before import +app_logger = logging.getLogger("app") +app_logger.info("PRE_IMPORT_FORMAT") + +# Import RedisVL +from redisvl.query.filter import Text # noqa: E402, F401 + +# Log after import +app_logger.info("POST_IMPORT_FORMAT") diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index a6e3dd02..83300d0c 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -1,3 +1,8 @@ +import importlib +import io +import logging +import re +import sys from functools import wraps import numpy as np @@ -441,3 +446,59 @@ def old_func(): with pytest.warns(DeprecationWarning): old_func() + + def test_logging_configuration_not_overridden(self): + """Test that RedisVL imports don't override existing logging configurations.""" + import os + import subprocess + + # Get the path to the helper script relative to this test file + current_dir = os.path.dirname(os.path.abspath(__file__)) + helper_script = os.path.join(current_dir, "logger_interference_checker.py") + + # Run the helper script in a separate process + result = subprocess.run( + [sys.executable, helper_script], capture_output=True, text=True + ) + + # Extract the log lines + output_lines = result.stdout.strip().split("\n") + pre_import_line = "" + post_import_line = "" + + for line in output_lines: + if "PRE_IMPORT_FORMAT" in line: + pre_import_line = line + elif "POST_IMPORT_FORMAT" in line: + post_import_line = line + + # Check if we found both lines + assert pre_import_line, "No pre-import log message found" + assert post_import_line, "No post-import log message found" + + # Print for debugging + print(f"Pre-import format: {pre_import_line}") + print(f"Post-import format: {post_import_line}") + + # Check format preservation + # Look for bracketed logger name format + has_bracketed_logger_pre = "[app]" in pre_import_line + has_bracketed_logger_post = "[app]" in post_import_line + assert has_bracketed_logger_pre == has_bracketed_logger_post, ( + f"Logger format changed from {'bracketed' if has_bracketed_logger_pre else 'unbracketed'} " + f"to {'bracketed' if has_bracketed_logger_post else 'unbracketed'}" + ) + + # Look for file/line information + has_file_line_pre = bool(re.search(r"\[\w+\.py:\d+\]", pre_import_line)) + has_file_line_post = bool(re.search(r"\[\w+\.py:\d+\]", post_import_line)) + assert ( + has_file_line_pre == has_file_line_post + ), f"File/line format changed: was present before: {has_file_line_pre}, present after: {has_file_line_post}" + + # Check date format (RedisVL strips the date portion) + has_date_pre = bool(re.match(r"\d{4}-\d{2}-\d{2}", pre_import_line)) + has_date_post = bool(re.match(r"\d{4}-\d{2}-\d{2}", post_import_line)) + assert ( + has_date_pre == has_date_post + ), f"Date format changed: was present before: {has_date_pre}, present after: {has_date_post}"