diff --git a/src/vllm_router/app.py b/src/vllm_router/app.py index 4bb8823e2..abe59d650 100644 --- a/src/vllm_router/app.py +++ b/src/vllm_router/app.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio +import logging import threading from contextlib import asynccontextmanager @@ -103,6 +104,28 @@ logger = init_logger(__name__) +class _EndpointAccessLogFilter(logging.Filter): + """Suppress uvicorn access-log records for a fixed set of request paths. + + Handy for silencing health/readiness probes (e.g. ``/health``, + ``/metrics``) that would otherwise flood the router logs while keeping + access logs for real traffic. uvicorn emits each access record with + positional ``args`` of ``(client_addr, method, path, http_version, + status_code)``; we match on ``path`` (ignoring any query string). + """ + + def __init__(self, endpoints): + super().__init__() + self._endpoints = {e.strip() for e in endpoints if e and e.strip()} + + def filter(self, record: logging.LogRecord) -> bool: + if self._endpoints and record.args and len(record.args) >= 3: + path = str(record.args[2]).split("?", 1)[0] + if path in self._endpoints: + return False + return True + + @asynccontextmanager async def lifespan(app: FastAPI): app.state.aiohttp_client_wrapper.start() @@ -393,6 +416,19 @@ def main(): # many concurrent requests active. set_ulimit() + # Optionally drop access logs for noisy probe endpoints. The filter is + # attached to the ``uvicorn.access`` logger before uvicorn configures its + # own logging; uvicorn's dictConfig replaces handlers but preserves + # existing logger filters, so the suppression survives both text and json + # log formats. + disabled_endpoints = parse_comma_separated_args( + args.disable_access_log_for_endpoints + ) + if disabled_endpoints: + logging.getLogger("uvicorn.access").addFilter( + _EndpointAccessLogFilter(disabled_endpoints) + ) + uvicorn_kwargs = { "host": args.host, "port": args.port, diff --git a/src/vllm_router/parsers/parser.py b/src/vllm_router/parsers/parser.py index 4a7c222f7..0fa1c9420 100644 --- a/src/vllm_router/parsers/parser.py +++ b/src/vllm_router/parsers/parser.py @@ -385,6 +385,15 @@ def parse_args(): help="Log output format. 'text' for human-readable colored output, " "'json' for structured JSON logging. Default is 'text'.", ) + parser.add_argument( + "--disable-access-log-for-endpoints", + type=str, + default=None, + help="Comma-separated list of request paths whose uvicorn access " + "logs should be suppressed, e.g. '/health,/metrics'. Useful to keep " + "liveness/readiness probe noise out of the router logs while " + "preserving access logs for real traffic.", + ) parser.add_argument( "--sentry-dsn",