fix(logging): parse JSON_LOGS env var so JSON_LOGS=False disables JSON logs

json_logs was derived with bool(os.getenv("JSON_LOGS", False)). os.getenv
returns a string (or None), never the bool default, so bool() is truthy for
every non-empty value including "False", "0", and "no". Once a user followed
the docs and set JSON_LOGS to enable it, there was no value (other than empty
string) that would turn it back off, and the flag also propagates to
litellm.json_logs which litellm-proxy-extras reads, corrupting its formatting
too.

Parse it case-insensitively so only "true" enables JSON logging, matching the
existing litellm_proxy_extras/_logging.py fallback. The parse is extracted into
a small pure helper so it is unit-testable without import-time side effects, and
inlining avoids a circular import with str_to_bool in secret_managers.main
(which imports from this module).
This commit is contained in:
Anas Khan 2026-07-06 15:40:35 +05:30
parent 60729f733e
commit 9148305238
No known key found for this signature in database
2 changed files with 33 additions and 1 deletions

View file

@ -77,7 +77,11 @@ class SecretRedactionFilter(logging.Filter):
_secret_filter = SecretRedactionFilter()
json_logs = bool(os.getenv("JSON_LOGS", False))
def _env_flag_enabled(value: Optional[str]) -> bool:
return (value or "").strip().lower() == "true"
json_logs = _env_flag_enabled(os.getenv("JSON_LOGS"))
# Create a handler for the logger (you may need to adapt this based on your needs)
log_level = os.getenv("LITELLM_LOG", "DEBUG")
numeric_level: str = getattr(logging, log_level.upper())

View file

@ -16,6 +16,7 @@ import litellm
from litellm._logging import (
ALL_LOGGERS,
JsonFormatter,
_env_flag_enabled,
_initialize_loggers_with_handler,
_turn_on_json,
verbose_logger,
@ -66,6 +67,33 @@ def test_json_mode_emits_one_record_per_logger(capfd):
assert "timestamp" in obj, "`timestamp` key missing"
@pytest.mark.parametrize(
"value, expected",
[
("True", True),
("true", True),
("TRUE", True),
(" true ", True),
("1", False),
("False", False),
("false", False),
("0", False),
("no", False),
("off", False),
("", False),
(None, False),
],
)
def test_env_flag_enabled_only_true_enables(value, expected):
"""
Regression: JSON_LOGS is a boolean env flag, so only "true" (case-insensitive)
may enable it. The previous bool(os.getenv("JSON_LOGS", False)) turned any
non-empty string, including "False"/"0"/"no", into True, so JSON logging could
never be disabled via the documented env var.
"""
assert _env_flag_enabled(value) is expected
def test_json_formatter_parses_embedded_json_message():
"""
Test that JsonFormatter parses embedded JSON in the message field and promotes