import { Hono } from 'hono'; export class HealthController { private app: Hono; constructor() { this.app = new Hono(); this.setupRoutes(); } private setupRoutes() { // Basic health check this.app.get('/', async (c) => { return c.json({ service: 'data-catalog', status: 'healthy', timestamp: new Date().toISOString(), version: process.env.SERVICE_VERSION || '1.0.0' }); }); // Detailed health check this.app.get('/detailed', async (c) => { try { const healthStatus = { service: 'data-catalog', status: 'healthy', timestamp: new Date().toISOString(), version: process.env.SERVICE_VERSION || '1.0.0', uptime: process.uptime(), memory: process.memoryUsage(), dependencies: { database: await this.checkDatabase(), search: await this.checkSearchService(), eventBus: await this.checkEventBus() } }; // Determine overall status based on dependencies const hasUnhealthyDependencies = Object.values(healthStatus.dependencies) .some(dep => dep.status !== 'healthy'); if (hasUnhealthyDependencies) { healthStatus.status = 'degraded'; } const statusCode = healthStatus.status === 'healthy' ? 200 : 503; return c.json(healthStatus, statusCode); } catch (error) { console.error('Health check error:', error); return c.json({ service: 'data-catalog', status: 'unhealthy', timestamp: new Date().toISOString(), error: error instanceof Error ? error.message : 'Unknown error' }, 503); } }); // Readiness check this.app.get('/ready', async (c) => { try { // Check if service is ready to accept requests const readyChecks = await Promise.all([ this.checkDatabase(), this.checkSearchService() ]); const isReady = readyChecks.every(check => check.status === 'healthy'); if (isReady) { return c.json({ service: 'data-catalog', ready: true, timestamp: new Date().toISOString() }); } else { return c.json({ service: 'data-catalog', ready: false, timestamp: new Date().toISOString(), checks: readyChecks }, 503); } } catch (error) { console.error('Readiness check error:', error); return c.json({ service: 'data-catalog', ready: false, timestamp: new Date().toISOString(), error: error instanceof Error ? error.message : 'Unknown error' }, 503); } }); // Liveness check this.app.get('/live', async (c) => { return c.json({ service: 'data-catalog', alive: true, timestamp: new Date().toISOString() }); }); } private async checkDatabase(): Promise<{ name: string; status: string; responseTime?: number }> { const start = Date.now(); try { // Simulate database check // In real implementation, this would ping the actual database await new Promise(resolve => setTimeout(resolve, 10)); return { name: 'database', status: 'healthy', responseTime: Date.now() - start }; } catch (error) { return { name: 'database', status: 'unhealthy', responseTime: Date.now() - start }; } } private async checkSearchService(): Promise<{ name: string; status: string; responseTime?: number }> { const start = Date.now(); try { // Simulate search service check // In real implementation, this would check search index health await new Promise(resolve => setTimeout(resolve, 5)); return { name: 'search', status: 'healthy', responseTime: Date.now() - start }; } catch (error) { return { name: 'search', status: 'unhealthy', responseTime: Date.now() - start }; } } private async checkEventBus(): Promise<{ name: string; status: string; responseTime?: number }> { const start = Date.now(); try { // Simulate event bus check // In real implementation, this would check message broker connectivity await new Promise(resolve => setTimeout(resolve, 3)); return { name: 'eventBus', status: 'healthy', responseTime: Date.now() - start }; } catch (error) { return { name: 'eventBus', status: 'unhealthy', responseTime: Date.now() - start }; } } public getApp(): Hono { return this.app; } }