From 38274825d99e8815275aaf448d042f617cb45053 Mon Sep 17 00:00:00 2001 From: Robert Helewka Date: Sun, 10 May 2026 18:32:20 -0400 Subject: [PATCH] Debugging startup failure --- mnemosyne/mnemosyne/views.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mnemosyne/mnemosyne/views.py b/mnemosyne/mnemosyne/views.py index f715c45..e9253f0 100644 --- a/mnemosyne/mnemosyne/views.py +++ b/mnemosyne/mnemosyne/views.py @@ -2,6 +2,8 @@ Mnemosyne project-level views — landing page and dashboard. """ +import logging + from django.contrib.auth.decorators import login_required from django.core.cache import cache from django.db import connection @@ -10,6 +12,8 @@ from django.shortcuts import render from llm_manager.models import LLMApi, LLMModel +logger = logging.getLogger(__name__) + def landing(request): """ @@ -85,6 +89,17 @@ def _check_s3() -> str | None: def ready(request): + """ + Readiness probe used by the compose healthcheck and any external + load balancer. Returns 200 with ``{"status": "ok"}`` when Postgres + + cache + S3 are all reachable, 503 with an ``errors`` dict otherwise. + + Every 503 emits an ERROR log line with the same error dict, so the + reason for an un-ready container surfaces in ``docker compose logs`` + immediately — otherwise the Django request logger only records the + bare "Service Unavailable: /ready/" status line, which tells you + nothing about which dependency is down. + """ errors = {} try: connection.ensure_connection() @@ -98,5 +113,9 @@ def ready(request): if s3_error: errors["s3"] = s3_error if errors: + # Logged on every failed probe, not just the first, because the + # failing dependency may change over time and silent failures + # here are the class of problem readiness probes exist to prevent. + logger.error("Readiness check failed: %s", errors) return JsonResponse({"status": "error", "errors": errors}, status=503) return JsonResponse({"status": "ok"})