feat: add detailed request logging to /api/score and global 422 handler
- Log incoming request (client, content-type, metrics, has_gt) on each /api/score call - Log scoring result (latency, skipped metrics, scores) on success - Register global RequestValidationError handler: logs url/content-type/errors so 422 causes are visible in server log without checking HTTP response body - Fix jsonable_encoder for exc.errors() to handle non-serializable ctx objects Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -7,15 +7,19 @@ the server starts even when the evaluation dependencies are not yet installed.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from webapp.api import evaluations, llm_profiles, pipeline, runs, scenarios, score
|
||||
|
||||
STATIC_DIR = Path(__file__).resolve().parent / "static"
|
||||
logger = logging.getLogger("webapp.server")
|
||||
|
||||
# OpenAPI tag metadata — controls the grouping and descriptions in /docs.
|
||||
OPENAPI_TAGS = [
|
||||
@@ -103,6 +107,21 @@ def create_app() -> FastAPI:
|
||||
app.include_router(pipeline.router)
|
||||
app.include_router(score.router)
|
||||
|
||||
@app.exception_handler(RequestValidationError)
|
||||
async def validation_exception_handler(request: Request, exc: RequestValidationError) -> JSONResponse:
|
||||
"""Log full validation error detail to help diagnose 422 responses."""
|
||||
errors = jsonable_encoder(exc.errors())
|
||||
logger.warning(
|
||||
"[422] validation error url=%s content_type=%s errors=%s",
|
||||
request.url.path,
|
||||
request.headers.get("content-type", ""),
|
||||
errors,
|
||||
)
|
||||
return JSONResponse(
|
||||
status_code=422,
|
||||
content={"detail": errors},
|
||||
)
|
||||
|
||||
@app.get("/api/health", tags=["meta"])
|
||||
def health() -> dict[str, str]:
|
||||
"""Report basic liveness so the UI can confirm the server is reachable."""
|
||||
|
||||
Reference in New Issue
Block a user