Skip to content

feat(router): add --disable-access-log-for-endpoints to silence probe logs#979

Open
Anai-Guo wants to merge 3 commits into
vllm-project:mainfrom
Anai-Guo:feat/router-disable-access-log-endpoints
Open

feat(router): add --disable-access-log-for-endpoints to silence probe logs#979
Anai-Guo wants to merge 3 commits into
vllm-project:mainfrom
Anai-Guo:feat/router-disable-access-log-endpoints

Conversation

@Anai-Guo

Copy link
Copy Markdown
Contributor

Summary

Closes #967.

The router container logs every liveness-/readinessProbe hit, which floods the logs. The model containers can already suppress this with --disable-access-log-for-endpoints; this PR brings the same capability to vllm_router.

What changed

  • New CLI flag --disable-access-log-for-endpoints (comma-separated paths, e.g. /health,/metrics).
  • A small logging.Filter (_EndpointAccessLogFilter) is attached to the uvicorn.access logger before uvicorn.run. It matches on the request path (ignoring any query string) and drops only the matching access records — error logs and --log-stats are untouched.

Why this approach

uvicorn emits each access record with positional args of (client_addr, method, path, http_version, status_code), so matching on args[2] is robust across formatters. uvicorn's dictConfig replaces handlers but preserves existing logger filters, so the suppression works in both text and json log formats. When the flag is unset, behavior is unchanged.

Usage

python -m vllm_router.app ... --disable-access-log-for-endpoints /health,/metrics

🤖 Generated with Claude Code

… logs

Adds a router CLI flag to suppress uvicorn access-log lines for a
comma-separated set of request paths (e.g. /health,/metrics), mirroring
the probe-noise suppression already available on the model containers.
Implemented as a logging.Filter attached to the uvicorn.access logger,
which survives uvicorn's dictConfig in both text and json log formats.

Closes vllm-project#967

Signed-off-by: Tai An <antai12232931@outlook.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a feature to suppress uvicorn access logs for specific endpoints (such as health probes) via a new --disable-access-log-for-endpoints command-line argument. The implementation includes a custom logging filter, _EndpointAccessLogFilter, which is registered on the uvicorn.access logger. The review feedback highlights two important issues: first, registering the filter before uvicorn.run() is ineffective because uvicorn's internal logging configuration clears existing filters, so it should instead be applied within the FastAPI lifespan context manager; second, a potential KeyError could occur if record.args is a dictionary rather than a sequence, which can be resolved by explicitly checking its type before indexing.

Comment thread src/vllm_router/app.py
Comment on lines +419 to +430
# 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)
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In Python's logging.config.dictConfig (which uvicorn calls during startup), any existing filters on loggers are cleared if they are not explicitly defined in the configuration dictionary (unless incremental=True is used, which is not the case here). As a result, adding the filter to uvicorn.access before calling uvicorn.run() will cause it to be silently removed during startup, making the suppression ineffective.

To resolve this, we should store the parsed endpoints in app.state and apply the filter inside the FastAPI lifespan context manager, which executes after uvicorn has completed its logging configuration.

For example, in lifespan:

@asynccontextmanager
async def lifespan(app: FastAPI):
    # ... existing code ...
    disabled_endpoints = getattr(app.state, "disable_access_log_for_endpoints", None)
    if disabled_endpoints:
        logging.getLogger("uvicorn.access").addFilter(
            _EndpointAccessLogFilter(disabled_endpoints)
        )
    yield
    # ...
Suggested change
# 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)
)
app.state.disable_access_log_for_endpoints = parse_comma_separated_args(
args.disable_access_log_for_endpoints
)

Comment thread src/vllm_router/app.py
Comment on lines +121 to +126
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If record.args is a dictionary (which can happen if a log message uses named placeholders), len(record.args) returns the number of keys. If the dictionary has 3 or more keys, record.args[2] will raise a KeyError because 2 is not a valid key. To prevent potential logging crashes, we should explicitly verify that record.args is a sequence (like a tuple or list) before indexing it.

Suggested change
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
def filter(self, record: logging.LogRecord) -> bool:
if (
self._endpoints
and isinstance(record.args, (tuple, list))
and len(record.args) >= 3
):
path = str(record.args[2]).split("?", 1)[0]
if path in self._endpoints:
return False
return True

Anai-Guo added 2 commits June 28, 2026 18:08
…re-commit end-of-file hook

Signed-off-by: Tai An <antai12232931@outlook.com>
…nd-of-file hook

Signed-off-by: Tai An <antai12232931@outlook.com>
@Anai-Guo Anai-Guo force-pushed the feat/router-disable-access-log-endpoints branch from cd3e850 to 4d0e939 Compare June 29, 2026 01:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature: add Uvicorn logging parameters to vllm_router

1 participant