import { createServer, type Server } from "node:http"; import { sql } from "drizzle-orm"; import { db } from "./db.js"; import { env } from "./env.js"; import { logger } from "./logger.js"; export type HealthStatus = { ok: boolean; uptimeSec: number; db: "ok" | "error"; sessions?: Record; }; const started = Date.now(); let getSessionCounts: () => Record = () => ({}); export function setSessionCountsProvider(fn: () => Record): void { getSessionCounts = fn; } export async function buildHealth(): Promise { let dbStatus: "ok" | "error" = "ok"; try { await db.execute(sql`select 1`); } catch (err) { logger.warn({ err }, "health: db ping failed"); dbStatus = "error"; } return { ok: dbStatus === "ok", uptimeSec: Math.round((Date.now() - started) / 1000), db: dbStatus, sessions: getSessionCounts(), }; } export function startHealthServer(): Server { const server = createServer(async (req, res) => { if (req.url !== "/health") { res.writeHead(404).end("not found"); return; } const status = await buildHealth(); res.writeHead(status.ok ? 200 : 503, { "content-type": "application/json" }); res.end(JSON.stringify(status)); }); server.listen(env.BOT_HEALTH_PORT, () => { logger.info({ port: env.BOT_HEALTH_PORT }, "health server listening"); }); return server; }