diff --git a/indexer/indexer/app.py b/indexer/indexer/app.py index 3442d64..38631d3 100644 --- a/indexer/indexer/app.py +++ b/indexer/indexer/app.py @@ -142,10 +142,17 @@ def create_app() -> Flask: # Attach XRPC server to Flask app init_flask(server, app) - # Health check endpoint + # Health check endpoint (verifies DB connection) @app.route("/health") def health(): - return {"status": "ok"} + try: + session = db.get_session(engine) + # Quick DB check + session.execute(db.text("SELECT 1")) + session.close() + return {"status": "ok", "db": "connected"} + except Exception as e: + return {"status": "error", "db": str(e)}, 500 # Root endpoint with service info @app.route("/") diff --git a/tools/healthcheck.py b/tools/healthcheck.py index ca7b780..179f683 100644 --- a/tools/healthcheck.py +++ b/tools/healthcheck.py @@ -91,6 +91,22 @@ def check_last_publish() -> tuple[datetime | None, int]: return latest_time, recent_count +def check_xrpc_indexer() -> bool: + """Check if XRPC indexer API is healthy.""" + import urllib.request + import urllib.error + + try: + req = urllib.request.Request( + "https://central-production.up.railway.app/health", + headers={"User-Agent": "central-healthcheck"} + ) + with urllib.request.urlopen(req, timeout=10) as resp: + return resp.status == 200 + except (urllib.error.URLError, urllib.error.HTTPError, TimeoutError): + return False + + def check_cron_running() -> bool: """Check if cron jobs are configured.""" try: @@ -139,6 +155,12 @@ def run_healthcheck() -> dict: if not check_cron_running(): status["issues"].append("Cron jobs not configured") + # Check XRPC indexer + xrpc_healthy = check_xrpc_indexer() + status["metrics"]["xrpc_indexer"] = "healthy" if xrpc_healthy else "down" + if not xrpc_healthy: + status["issues"].append("XRPC indexer API is down (502/unreachable)") + # Set overall health status["healthy"] = len(status["issues"]) == 0