PH6.6 — Observability and production compose profile #62
No reviewers
Labels
No labels
ready-for-agent
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
patrick/Polaris!62
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/infra-observability"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
/metrics(backend/src/polaris/api/metrics.py) with a request-latency histogram keyed by method+route-template,taskqueue-depth/claim-latency gauges, and best-effortsolver_rungauges.solver_runisn't migrated onmainyet (PH1.2/T-E are still open PRs), so it's reflected for at scrape time rather than imported as a model — the endpoint just renders nothing extra until that table exists, instead of erroring.core/logging.pywithservice/environment/pidon every log line, an explicituseralias for the existingactor_sub, andbind_task_id/clear_task_idhelpers (same bind/unbind-around-the-work patternapi/middleware.pyalready uses forrequest_id) for the worker's task-claim loop to adopt.install_otel, called frominstall_metrics): lazily imported and opt-in viaPOLARIS_OTEL_ENABLED(plus the standardOTEL_*env vars), sinceopentelemetry-*isn't declared inpyproject.toml(sealed for this row) — disabled or package-missing both degrade to a clean no-op with a warning log line, never an error.trace_id/span_idget stitched into structlog output when a span is current.infra/compose/docker-compose.prod.yml: TLS termination at nginx (infra/nginx/prod.conf, HTTP redirects to HTTPS except the healthcheck) and TLS on the compose-bundled OpenLDAP (LDAPS only, plaintext389dropped from the prod stack). Certificates are self-signed for now, generated once per host byinfra/nginx/generate-self-signed-cert.sh/infra/ldap/generate-self-signed-cert.shinto git-ignoredcerts/directories.docs/07-architecture.mdanddocs/11-roadmap.mdperCLAUDE.md's rule for resolvedQnassumptions.Scope notes / seam requests for a future ticket
api/main.pyis sealed for this row, so the new latency middleware is installed from withinapi/metrics.py:install_metrics(already called bymain.py) rather than touching that file. The existingpolaris_http_requests_totalcounter (populated bymain.py's own middleware) still uses the raw request path; unifying it onto the same route-template label as the new histogram needs a smallmain.pychange — flagged as a follow-up seam request rather than widening this ticket.bind_task_id/clear_task_idare ready for the worker's task-claim loop (backend/src/polaris/worker/**, owned by PH0.3, outside this ticket's owned paths) to call around a handler invocation; not wired up there in this PR.opentelemetry-api,opentelemetry-sdk,opentelemetry-instrumentation-fastapi,opentelemetry-exporter-otlp-proto-http) aren't added topyproject.toml(sealed for this row) — the hooks are fully optional/lazily-imported so this isn't a hard dependency; adding the packages for real use is a separate seam request.Test plan
docker compose -f infra/compose/docker-compose.yml configparses cleanlydocker compose -f infra/compose/docker-compose.yml -f infra/compose/docker-compose.prod.yml --profile app configparses cleanlydocker compose -f infra/compose/docker-compose.yml -f infra/compose/docker-compose.dev.yml configparses cleanly (untouched by this PR, checked for regressions)infra/nginx/prod.confvalidated withnginx -tagainst a self-signed cert from the new generator scriptruff check/ruff format --checkon all touched backend filesmypy --strict(uv run mypy, project's ownfiles = ["src"]scope) — cleanpytest tests/unit -q— 37 passedpytest tests/integration -q -m integration(real Postgres via testcontainers) — 11 passed, including new task-queue-depth/claim-latency/solver_run-absence integration tests against a running PostgresCloses #47
🤖 Generated with Claude Code
https://claude.ai/code/session_013YioTVKBPoE6thZqbnTtnM