FastAPI / ASGI Diagnostics Middleware
======================================
Purpose
-------
Pure ASGI middleware that logs every HTTP request and response through
``_dbg()``, providing structured per-request diagnostics: HTTP method,
path, status code, client IP, and elapsed wall-clock time.
Responsibilities
----------------
- Implement ``DiagnosticsMiddleware`` as a pure ASGI callable that wraps
any ASGI application without requiring ``starlette.BaseHTTPMiddleware``.
- Log request entry at L2 (method, path, client IP).
- Log User-Agent header at L3 and all request/response headers at L4.
- Capture HTTP status code from the ``http.response.start`` ASGI event via
a lightweight ``send`` wrapper; no request or response bodies are buffered.
- Measure and report wall-clock elapsed time in milliseconds.
- Pass non-HTTP scopes (WebSocket, lifespan) through unchanged.
- Log application-level exceptions at L2 before re-raising them.
- Route all output through ``_dbg()`` using the configurable domain
(default: ``"HTTP"``).
Diagnostics
-----------
Domain: HTTP
Levels:
L2 — lifecycle (request start, response end, application errors)
L3 — semantic details (User-Agent, 4xx/5xx status class)
L4 — deep tracing (all request and response headers)
Contracts
---------
- Must never suppress exceptions raised by the wrapped application;
errors are logged at L2 and then re-raised unchanged.
- Must not buffer or modify request or response bodies.
- Must pass non-HTTP ASGI scopes (WebSocket, lifespan) through unchanged.
- Does not require FastAPI at import time; works with any ASGI framework.
Install the ``[fastapi]`` optional extra for FastAPI framework utilities::
pip install oc_diagnostics[fastapi]
- The ``HTTP`` domain must be configured in the project's
``diagnostics/debug_config.json`` with a non-zero level for log output
to appear (``DEBUG_LEVELS.get("HTTP", 0)`` defaults to disabled).