mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-06 08:16:43 +00:00
Merge 36018b8013 into 43ae3507e0
This commit is contained in:
commit
ed1ce16d5b
4 changed files with 71 additions and 1 deletions
|
|
@ -473,6 +473,11 @@ migrationJob:
|
|||
#
|
||||
# Setting LITELLM_LOG inside `envVars:` below also wins: the template skips
|
||||
# this injection entirely when envVars already defines LITELLM_LOG.
|
||||
#
|
||||
# At WARNING or above, uvicorn inherits this level too, which silences the
|
||||
# per-request access log line that liveness and readiness probes would
|
||||
# otherwise emit on every poll. At INFO or below uvicorn keeps its own
|
||||
# default, so access logs stay on.
|
||||
logLevel: INFO
|
||||
|
||||
# Additional environment variables to be added to the deployment as a map of key-value pairs
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import os
|
|||
import sys
|
||||
from datetime import datetime
|
||||
from logging import Formatter
|
||||
from types import MappingProxyType
|
||||
from typing import Any, Final
|
||||
|
||||
import litellm
|
||||
|
|
@ -622,6 +623,28 @@ def _get_uvicorn_json_log_config():
|
|||
return log_config
|
||||
|
||||
|
||||
_UVICORN_LOG_LEVELS_QUIETER_THAN_INFO: Final = MappingProxyType(
|
||||
{
|
||||
"WARN": "warning",
|
||||
"WARNING": "warning",
|
||||
"ERROR": "error",
|
||||
"FATAL": "critical",
|
||||
"CRITICAL": "critical",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def get_uvicorn_log_level() -> str | None:
|
||||
"""Uvicorn's log level to inherit from LITELLM_LOG, or None to leave uvicorn's default alone.
|
||||
|
||||
Only levels quieter than INFO are inherited. uvicorn.access logs one line per request, so at
|
||||
WARNING or above an operator asking for less noise also means the health probe access lines.
|
||||
Levels at or below INFO are not propagated: LITELLM_LOG defaults to DEBUG, and mapping that
|
||||
onto uvicorn would turn on asgi-internals logging nobody asked for.
|
||||
"""
|
||||
return _UVICORN_LOG_LEVELS_QUIETER_THAN_INFO.get(log_level.upper())
|
||||
|
||||
|
||||
def _turn_on_json():
|
||||
"""
|
||||
Turn on JSON logging
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ class ProxyInitializationHelpers:
|
|||
import uvicorn
|
||||
|
||||
import litellm
|
||||
from litellm._logging import _get_uvicorn_json_log_config
|
||||
from litellm._logging import _get_uvicorn_json_log_config, get_uvicorn_log_level
|
||||
|
||||
uvicorn_args: Final = {
|
||||
"app": "litellm.proxy.proxy_server:app",
|
||||
|
|
@ -268,6 +268,10 @@ class ProxyInitializationHelpers:
|
|||
elif litellm.json_logs:
|
||||
# Use JSON log config for uvicorn to ensure all logs (including exceptions) are JSON
|
||||
uvicorn_args["log_config"] = _get_uvicorn_json_log_config()
|
||||
else:
|
||||
uvicorn_log_level = get_uvicorn_log_level()
|
||||
if uvicorn_log_level is not None:
|
||||
uvicorn_args["log_level"] = uvicorn_log_level
|
||||
if keepalive_timeout is not None:
|
||||
uvicorn_args["timeout_keep_alive"] = keepalive_timeout
|
||||
if timeout_worker_healthcheck is not None:
|
||||
|
|
|
|||
|
|
@ -136,6 +136,44 @@ class TestProxyInitializationHelpers:
|
|||
)
|
||||
assert args["timeout_worker_healthcheck"] == 15
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"litellm_log, expected_uvicorn_level",
|
||||
[
|
||||
("WARNING", "warning"),
|
||||
("WARN", "warning"),
|
||||
("warning", "warning"),
|
||||
("ERROR", "error"),
|
||||
("CRITICAL", "critical"),
|
||||
("FATAL", "critical"),
|
||||
],
|
||||
)
|
||||
def test_uvicorn_log_level_follows_litellm_log_when_quieter_than_info(
|
||||
self, litellm_log, expected_uvicorn_level
|
||||
):
|
||||
with patch("litellm._logging.log_level", litellm_log):
|
||||
args = ProxyInitializationHelpers._get_default_unvicorn_init_args(
|
||||
"localhost", 8000
|
||||
)
|
||||
assert args["log_level"] == expected_uvicorn_level
|
||||
|
||||
@pytest.mark.parametrize("litellm_log", ["DEBUG", "INFO", "NOTSET", "nonsense"])
|
||||
def test_uvicorn_log_level_is_left_alone_when_litellm_log_is_not_quieter(
|
||||
self, litellm_log
|
||||
):
|
||||
with patch("litellm._logging.log_level", litellm_log):
|
||||
args = ProxyInitializationHelpers._get_default_unvicorn_init_args(
|
||||
"localhost", 8000
|
||||
)
|
||||
assert "log_level" not in args
|
||||
|
||||
def test_explicit_log_config_wins_over_litellm_log(self):
|
||||
with patch("litellm._logging.log_level", "WARNING"):
|
||||
args = ProxyInitializationHelpers._get_default_unvicorn_init_args(
|
||||
"localhost", 8000, "log_config.json"
|
||||
)
|
||||
assert args["log_config"] == "log_config.json"
|
||||
assert "log_level" not in args
|
||||
|
||||
def test_installed_uvicorn_supports_worker_flags(self):
|
||||
params = inspect.signature(uvicorn.Config.__init__).parameters
|
||||
assert "timeout_worker_healthcheck" in params
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue