Skip to content

Support optionally disabling uvicorn access logs #254

Description

@fercor-cisco

Summary

agent_control_server always emits uvicorn's built-in uvicorn.access request log and provides no way to turn it off. When the server is embedded in a host that already emits its own structured request log (via its own ASGI middleware), this produces a duplicate line per request — often in a different format. Add an opt-out flag so the built-in access log can be disabled without affecting error/app logging.

Background

run() in server/src/agent_control_server/main.py calls uvicorn.run(app, ...) with log_level set but no control over uvicorn's access log:

uvicorn_kwargs: dict[str, Any] = {
    "host": settings.host,
    "port": settings.port,
    "log_level": get_uvicorn_log_level_name(_default_log_level()).lower(),
}
if not should_configure_logging():
    uvicorn_kwargs["log_config"] = None
uvicorn.run(app, **uvicorn_kwargs)

There's already a precedent for this kind of opt-out: AGENT_CONTROL_CONFIGURE_LOGGING=false lets an embedder own logging config and passes log_config=None to uvicorn. But that flag does not stop the access log — uvicorn's Config.configure_logging() unconditionally runs its log_level branch (independent of log_config), which resets uvicorn.access to INFO. So even with configure_logging=false, and even if the embedder raises uvicorn.access to WARNING beforehand, uvicorn clobbers it back to INFO and the access line is emitted anyway.

The only uvicorn lever that reliably suppresses the access log regardless of level or config ordering is the access_log kwarg. When access_log=False, uvicorn clears uvicorn.access's handlers and sets propagate=False, so its per-connection hasHandlers() gate is False and it never calls access_logger.info(...) at all. It's currently not plumbed through.

Proposed change

Add a settings field and pass it through to uvicorn.run, defaulting to current behavior (True).

server/src/agent_control_server/config.py — in LoggingSettings:

access_log: bool = _env_alias_field(True, "AGENT_CONTROL_ACCESS_LOG")

server/src/agent_control_server/main.py — in run():

uvicorn_kwargs: dict[str, Any] = {
    "host": settings.host,
    "port": settings.port,
    "log_level": get_uvicorn_log_level_name(_default_log_level()).lower(),
    "access_log": LoggingSettings().access_log,
}

Acceptance criteria

  • New setting access_log on LoggingSettings, defaulting to True (no behavior change for existing users).
  • Configurable via AGENT_CONTROL_ACCESS_LOG (consistent with AGENT_CONTROL_CONFIGURE_LOGGING).
  • With AGENT_CONTROL_ACCESS_LOG=false, no uvicorn.access line is emitted for requests, and this holds whether configure_logging is on or off.
  • Error/app logging (uvicorn.error, application loggers) is unaffected.
  • Documented in the README/settings reference alongside the other AGENT_CONTROL_LOG_* options.

Use case

Embedders (e.g. a service that injects its own request-logging middleware onto the agent-control app) can set AGENT_CONTROL_ACCESS_LOG=false to make their own middleware the sole request log, eliminating the duplicate line.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions