learning_ai_common_plat/services/monitoring/health-check.ts

58 lines
2.2 KiB
TypeScript

/**
* Monitoring & Health Check — aggregates health from all services.
*
* Standalone script that polls each service's /health endpoint and
* reports combined status. Can be run as a cron job, GitHub Action,
* or standalone HTTP endpoint.
*
* Usage:
* npx tsx services/monitoring/health-check.ts # one-shot check
* npx tsx services/monitoring/health-check.ts --serve # HTTP server on :4004
*
* Environment:
* BACKEND_URL (default: http://localhost:8000)
* GROWTH_SERVICE_URL (default: http://localhost:4001)
* BILLING_SERVICE_URL (default: http://localhost:4002)
* PLATFORM_SERVICE_URL (default: http://localhost:4003)
* ADMIN_DASHBOARD_URL (default: http://localhost:3001)
* USER_DASHBOARD_URL (default: http://localhost:3002)
*/
import { DEFAULT_SERVICES, generateHealthReport } from '@bytelyst/monitoring';
// ── CLI / HTTP server mode ──
const args = process.argv.slice(2);
if (args.includes('--serve')) {
// Run as HTTP server for continuous monitoring
const { createServer } = await import('http');
const PORT = Number(process.env.MONITOR_PORT || 4004);
const server = createServer(async (_req, res) => {
const report = await generateHealthReport(DEFAULT_SERVICES);
res.writeHead(report.overall === 'healthy' ? 200 : 503, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(report, null, 2));
});
server.listen(PORT, () => {
console.log(`🩺 Monitoring dashboard running on http://localhost:${PORT}`);
console.log(` Checking ${DEFAULT_SERVICES.length} services every request`);
});
} else {
// One-shot check
const report = await generateHealthReport(DEFAULT_SERVICES);
const icon = { healthy: '✅', degraded: '⚠️', down: '❌' };
console.log(`\n${icon[report.overall]} Overall: ${report.overall.toUpperCase()}\n`);
for (const svc of report.services) {
const sIcon = { healthy: '✅', unhealthy: '⚠️', unreachable: '❌' };
console.log(
` ${sIcon[svc.status]} ${svc.name.padEnd(20)} ${svc.responseTimeMs}ms${svc.error ? `${svc.error}` : ''}`
);
}
console.log(`\nHealthy: ${report.summary.healthy}/${report.summary.total}`);
process.exit(report.overall === 'healthy' ? 0 : 1);
}