From 9d58d872ac8155f31537e3c3fc59f4a4162cba1f Mon Sep 17 00:00:00 2001 From: Cole McIntosh Date: Fri, 27 Jun 2025 11:34:38 -0600 Subject: [PATCH] fix: set logger levels based on LITELLM_LOG environment variable - Initialize verbose_logger, verbose_proxy_logger, and verbose_router_logger with the correct log level - Ensures loggers respect the LITELLM_LOG environment variable setting - Fixes part of issue #9815 where logs were shown regardless of log level setting Part 1/2 of fix for #9815 --- litellm/_logging.py | 5 ++ .../test_logger_level_initialization.py | 63 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 tests/test_litellm/test_logger_level_initialization.py diff --git a/litellm/_logging.py b/litellm/_logging.py index 356bb3dcaf7..0edaa6d67e0 100644 --- a/litellm/_logging.py +++ b/litellm/_logging.py @@ -103,6 +103,11 @@ verbose_proxy_logger = logging.getLogger("LiteLLM Proxy") verbose_router_logger = logging.getLogger("LiteLLM Router") verbose_logger = logging.getLogger("LiteLLM") +# Set the logger level based on LITELLM_LOG environment variable +verbose_proxy_logger.setLevel(numeric_level) +verbose_router_logger.setLevel(numeric_level) +verbose_logger.setLevel(numeric_level) + # Add the handler to the logger verbose_router_logger.addHandler(handler) verbose_proxy_logger.addHandler(handler) diff --git a/tests/test_litellm/test_logger_level_initialization.py b/tests/test_litellm/test_logger_level_initialization.py new file mode 100644 index 00000000000..2e6d9521cbc --- /dev/null +++ b/tests/test_litellm/test_logger_level_initialization.py @@ -0,0 +1,63 @@ +"""Test that loggers respect LITELLM_LOG environment variable""" +import logging +import os +import sys + +import pytest + +sys.path.insert(0, os.path.abspath("../../..")) + + +def test_logger_level_respects_env_var(monkeypatch): + """ + Test that loggers are initialized with the correct level based on LITELLM_LOG env var. + This verifies the fix for issue #9815 where loggers ignored the LITELLM_LOG setting. + """ + # Test different log levels + test_cases = [ + ("DEBUG", logging.DEBUG), + ("INFO", logging.INFO), + ("WARNING", logging.WARNING), + ("ERROR", logging.ERROR), + ("CRITICAL", logging.CRITICAL), + ] + + for env_level, expected_numeric_level in test_cases: + # Set the environment variable + monkeypatch.setenv("LITELLM_LOG", env_level) + + # Re-import the logging module to pick up the new env var + import importlib + import litellm._logging + importlib.reload(litellm._logging) + + # Check that all loggers have the correct level + assert litellm._logging.verbose_logger.level == expected_numeric_level, \ + f"verbose_logger level should be {expected_numeric_level} for LITELLM_LOG={env_level}" + + assert litellm._logging.verbose_proxy_logger.level == expected_numeric_level, \ + f"verbose_proxy_logger level should be {expected_numeric_level} for LITELLM_LOG={env_level}" + + assert litellm._logging.verbose_router_logger.level == expected_numeric_level, \ + f"verbose_router_logger level should be {expected_numeric_level} for LITELLM_LOG={env_level}" + + +def test_handler_and_logger_levels_match(monkeypatch): + """ + Test that both handler and logger levels are set to the same value. + This ensures consistent behavior across the logging system. + """ + monkeypatch.setenv("LITELLM_LOG", "WARNING") + + # Re-import to apply settings + import importlib + import litellm._logging + importlib.reload(litellm._logging) + + # Get the handler level (first handler should be our configured one) + handler_level = litellm._logging.handler.level + + # All loggers should have the same level as the handler + assert litellm._logging.verbose_logger.level == handler_level + assert litellm._logging.verbose_proxy_logger.level == handler_level + assert litellm._logging.verbose_router_logger.level == handler_level \ No newline at end of file