Add structured logging throughout the backend
Request-level logging middleware (method/path/status/duration), per-module loggers in routes/services (nearby search radius expansion, 404s, name search), LOG_LEVEL setting wired through docker-compose, and seed_loader converted from print() to logging. Verified: pytest passes, and manually confirmed log lines appear for both successful and 404 requests via `docker compose logs api`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
188bf01d6e
commit
be67902b45
11 changed files with 114 additions and 4 deletions
|
|
@ -1,4 +1,11 @@
|
|||
import logging
|
||||
import time
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import Response
|
||||
|
||||
request_logger = logging.getLogger("guidecity.http")
|
||||
|
||||
|
||||
def configure_logging(level: int = logging.INFO) -> None:
|
||||
|
|
@ -6,3 +13,25 @@ def configure_logging(level: int = logging.INFO) -> None:
|
|||
level=level,
|
||||
format="%(asctime)s %(levelname)s %(name)s %(message)s",
|
||||
)
|
||||
|
||||
|
||||
async def log_requests(
|
||||
request: Request,
|
||||
call_next: Callable[[Request], Awaitable[Response]],
|
||||
) -> Response:
|
||||
"""Logs method/path/status/duration for every request handled by the app."""
|
||||
start = time.perf_counter()
|
||||
try:
|
||||
response = await call_next(request)
|
||||
except Exception:
|
||||
duration_ms = (time.perf_counter() - start) * 1000
|
||||
request_logger.exception(
|
||||
"%s %s -> unhandled exception (%.1fms)", request.method, request.url.path, duration_ms
|
||||
)
|
||||
raise
|
||||
|
||||
duration_ms = (time.perf_counter() - start) * 1000
|
||||
request_logger.info(
|
||||
"%s %s -> %d (%.1fms)", request.method, request.url.path, response.status_code, duration_ms
|
||||
)
|
||||
return response
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue